agora inbox for pgsql-hackers@postgresql.orghelp / color / mirror / Atom feed
[PATCH v5 01/12] review docs for pg12dev 132+ messages / 4 participants [nested] [flat]
* [PATCH v1 2/8] review docs for pg12dev @ 2019-03-28 23:50 Justin Pryzby <pryzbyj@telsasoft.com> 0 siblings, 0 replies; 132+ messages in thread From: Justin Pryzby @ 2019-03-28 23:50 UTC (permalink / raw) --- doc/src/sgml/bloom.sgml | 2 +- doc/src/sgml/catalogs.sgml | 4 ++-- doc/src/sgml/config.sgml | 13 ++++++----- doc/src/sgml/ecpg.sgml | 18 +++++++------- doc/src/sgml/libpq.sgml | 2 +- doc/src/sgml/monitoring.sgml | 30 ++++++++++++------------ doc/src/sgml/perform.sgml | 8 +++---- doc/src/sgml/ref/alter_table.sgml | 4 ++-- doc/src/sgml/ref/create_index.sgml | 4 ++-- doc/src/sgml/ref/pg_rewind.sgml | 15 ++++++------ doc/src/sgml/ref/pgbench.sgml | 6 ++--- doc/src/sgml/ref/reindex.sgml | 2 +- doc/src/sgml/sources.sgml | 48 +++++++++++++++++++------------------- doc/src/sgml/xfunc.sgml | 12 +++++----- 14 files changed, 82 insertions(+), 86 deletions(-) diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml index 6eeadde..c341b65 100644 --- a/doc/src/sgml/bloom.sgml +++ b/doc/src/sgml/bloom.sgml @@ -65,7 +65,7 @@ <para> Number of bits generated for each index column. Each parameter's name refers to the number of the index column that it controls. The default - is <literal>2</literal> bits and maximum is <literal>4095</literal>. Parameters for + is <literal>2</literal> bits and the maximum is <literal>4095</literal>. Parameters for index columns not actually used are ignored. </para> </listitem> diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index f4aabf5..ad4d150 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -3051,7 +3051,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l simplifies <command>ATTACH/DETACH PARTITION</command> operations: the partition dependencies need only be added or removed. Example: a child partitioned index is made partition-dependent - on both the partition table it is on and the parent partitioned + on both the table partition and the parent partitioned index, so that it goes away if either of those is dropped, but not otherwise. The dependency on the parent index is primary, so that if the user tries to drop the child partitioned index, @@ -3114,7 +3114,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l Note that it's quite possible for two objects to be linked by more than one <structname>pg_depend</structname> entry. For example, a child partitioned index would have both a partition-type dependency on its - associated partition table, and an auto dependency on each column of + associated table partition, and an auto dependency on each column of that table that it indexes. This sort of situation expresses the union of multiple dependency semantics. A dependent object can be dropped without <literal>CASCADE</literal> if any of its dependencies satisfies diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 9b66e7f..5f6873d 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -112,7 +112,7 @@ For example, <literal>30.1 GB</literal> will be converted to <literal>30822 MB</literal> not <literal>32319628902 B</literal>. If the parameter is of integer type, a final rounding to integer - occurs after any units conversion. + occurs after any unit conversion. </para> </listitem> @@ -3408,7 +3408,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows current when the base backup was taken. The value <literal>latest</literal> recovers to the latest timeline found in the archive, which is useful in - a standby server. <literal>latest</literal> is the default. + a standby server. The default is <literal>latest</literal>. </para> <para> @@ -3515,7 +3515,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows servers or streaming base backup clients (i.e., the maximum number of simultaneously running WAL sender processes). The default is <literal>10</literal>. The value <literal>0</literal> means - replication is disabled. Abrupt streaming client disconnection might + replication is disabled. Abrupt disconnection of a streaming client might leave an orphaned connection slot behind until a timeout is reached, so this parameter should be set slightly higher than the maximum number of expected clients so disconnected clients can immediately @@ -4135,8 +4135,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class=" This parameter is intended for use with streaming replication deployments; however, if the parameter is specified it will be honored in all cases. - <varname>hot_standby_feedback</varname> will be delayed by use of this feature - which could lead to bloat on the master; use both together with care. + <varname>hot_standby_feedback</varname> will be delayed by use of this feature. + Combinining these settings could lead to bloat on the master, so should + be done only with care. <warning> <para> @@ -6853,7 +6854,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; <para> Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs - all autovacuum actions. Minus-one (the default) disables logging + all autovacuum actions. <literal>-1</literal> (the default) disables logging autovacuum actions. For example, if you set this to <literal>250ms</literal> then all automatic vacuums and analyzes that run 250ms or longer will be logged. In addition, when this parameter is diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index d5ee6a5..798aae4 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -662,7 +662,7 @@ EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>; not really useful in real applications. This section explains in detail how you can pass data between your C program and the embedded SQL statements using a simple mechanism called - <firstterm>host variables</firstterm>. In an embedded SQL program we + <firstterm>host variables</firstterm>. In an embedded SQL program we consider the SQL statements to be <firstterm>guests</firstterm> in the C program code which is the <firstterm>host language</firstterm>. Therefore the variables of the C program are called <firstterm>host @@ -979,7 +979,7 @@ EXEC SQL END DECLARE SECTION; <para> The other way is using the <type>VARCHAR</type> type, which is a - special type provided by ECPG. The definition on an array of + special type provided by ECPG. The definition of an array of type <type>VARCHAR</type> is converted into a named <type>struct</type> for every variable. A declaration like: <programlisting> @@ -989,7 +989,7 @@ VARCHAR var[180]; <programlisting> struct varchar_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts the string + The member <structfield>arr</structfield> stores the string including a terminating zero byte. Thus, to store a string in a <type>VARCHAR</type> host variable, the host variable has to be declared with the length including the zero byte terminator. The @@ -1209,8 +1209,8 @@ EXEC SQL END DECLARE SECTION; <title id="ecpg-type-bytea">bytea</title> <para> - The handling of the <type>bytea</type> type is also similar to - the <type>VARCHAR</type>. The definition on an array of type + The handling of the <type>bytea</type> type is similar to + the <type>VARCHAR</type>. The definition of an array of type <type>bytea</type> is converted into a named struct for every variable. A declaration like: <programlisting> @@ -1220,9 +1220,8 @@ bytea var[180]; <programlisting> struct bytea_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts binary format - data. It also can handle even <literal>'\0'</literal> as part of - data unlike <type>VARCHAR</type>. + The member <structfield>arr</structfield> stores binary format + data, which can include zero bytes, unlike <type>VARCHAR</type>. The data is converted from/to hex format and sent/received by ecpglib. </para> @@ -7571,8 +7570,7 @@ PREPARE <replaceable class="parameter">name</replaceable> FROM <replaceable clas <listitem> <para> A literal C string or a host variable containing a preparable - statement, one of the SELECT, INSERT, UPDATE, or - DELETE. + statement (SELECT, INSERT, UPDATE, or DELETE). </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index c1d1b6b..06b0076 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1122,7 +1122,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname <term><literal>connect_timeout</literal></term> <listitem> <para> - Maximum wait for connection, in seconds (write as a decimal integer, + Maximum time to wait while connecting, in seconds (write as a decimal integer, e.g. <literal>10</literal>). Zero, negative, or not specified means wait indefinitely. The minimum allowed timeout is 2 seconds, therefore a value of <literal>1</literal> is interpreted as <literal>2</literal>. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index f1df14b..a5bf49c 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -271,13 +271,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <para> Some of the information in the dynamic statistics views shown in <xref linkend="monitoring-stats-dynamic-views-table"/> is security restricted. - Ordinary users can only see all the information about their own sessions - (sessions belonging to a role that they are a member of). In rows about + Ordinary users can only see all information about their own sessions + (sessions belonging to a role of which they are a member). In rows for other sessions, many columns will be null. Note, however, that the existence of a session and its general properties such as its sessions user and database are visible to all users. Superusers and members of the built-in role <literal>pg_read_all_stats</literal> (see also <xref - linkend="default-roles"/>) can see all the information about all sessions. + linkend="default-roles"/>) can see all information about all sessions. </para> <table id="monitoring-stats-dynamic-views-table"> @@ -3411,16 +3411,16 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>VACUUM Progress Reporting</title> <para> - Whenever <command>VACUUM</command> is running, the - <structname>pg_stat_progress_vacuum</structname> view will contain - one row for each backend (including autovacuum worker processes) that is - currently vacuuming. The tables below describe the information + The <structname>pg_stat_progress_vacuum</structname> view will contain one + row for each backend that is running <command>VACUUM</command>, including + autovacuum worker processes. + The tables below describe the information that will be reported and provide information about how to interpret it. - Progress for <command>VACUUM FULL</command> commands is reported via - <structname>pg_stat_progress_cluster</structname> - because both <command>VACUUM FULL</command> and <command>CLUSTER</command> - rewrite the table, while regular <command>VACUUM</command> only modifies it - in place. See <xref linkend='cluster-progress-reporting'/>. + Progress for <command>VACUUM FULL</command> commands is instead reported via + <structname>pg_stat_progress_cluster</structname>, + because <command>VACUUM FULL</command> rewrites the table, like <command>CLUSTER</command>, + while regular <command>VACUUM</command> modifies it in place. See <xref linkend='cluster-progress-reporting'/>. + </para> <table id="pg-stat-progress-vacuum-view" xreflabel="pg_stat_progress_vacuum"> @@ -3603,9 +3603,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>CLUSTER Progress Reporting</title> <para> - Whenever <command>CLUSTER</command> or <command>VACUUM FULL</command> is - running, the <structname>pg_stat_progress_cluster</structname> view will - contain a row for each backend that is currently running either command. + The <structname>pg_stat_progress_cluster</structname> view will contain a + row for each backend that is running either + <command>CLUSTER</command> or <command>VACUUM FULL</command>. The tables below describe the information that will be reported and provide information about how to interpret it. </para> diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml index a84be85..65c161b 100644 --- a/doc/src/sgml/perform.sgml +++ b/doc/src/sgml/perform.sgml @@ -899,10 +899,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 Generally, the <command>EXPLAIN</command> output will display details for every plan node which was generated by the query planner. However, there are cases where the executor is able to determine that certain nodes are - not required; currently, the only node types to support this are the - <literal>Append</literal> and <literal>MergeAppend</literal> nodes. These - node types have the ability to discard subnodes which they are able to - determine won't contain any records required by the query. It is possible + not required; currently, the only node types to support this are + <literal>Append</literal> and <literal>MergeAppend</literal>, which + are able to discard subnodes when it's deduced that + they will not contain any records required by the query. It is possible to determine that nodes have been removed in this way by the presence of a "Subplans Removed" property in the <command>EXPLAIN</command> output. </para> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index e360728..679e51a 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -219,7 +219,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM <para> <literal>SET NOT NULL</literal> may only be applied to a column - providing none of the records in the table contain a + provided none of the records in the table contain a <literal>NULL</literal> value for the column. Ordinarily this is checked during the <literal>ALTER TABLE</literal> by scanning the entire table; however, if a valid <literal>CHECK</literal> constraint is @@ -642,7 +642,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM When applied to a partitioned table, nothing is moved, but any partitions created afterwards with <command>CREATE TABLE PARTITION OF</command> will use that tablespace, - unless the <literal>TABLESPACE</literal> clause is used to override it. + unless overridden by its <literal>TABLESPACE</literal> clause. </para> <para> diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index d9d95b2..14a557a 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -181,8 +181,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= </para> <para> - Currently, the B-tree and the GiST index access methods supports this - feature. In B-tree and the GiST indexes, the values of columns listed + Currently, only the B-tree and GiST index access methods support this + feature. In B-tree and GiST indexes, the values of columns listed in the <literal>INCLUDE</literal> clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index 53a64ee..cf77552 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -106,15 +106,14 @@ PostgreSQL documentation </para> <para> - <application>pg_rewind</application> will fail immediately if it finds - files it cannot write directly to. This can happen for example when - the source and the target server use the same file mapping for read-only - SSL keys and certificates. If such files are present on the target server + <application>pg_rewind</application> will fail immediately if it experiences + a write error. This can happen for example when + the source and target server use the same file mapping for read-only + SSL keys and certificates. If such files are present on the target server, it is recommended to remove them before running - <application>pg_rewind</application>. After doing the rewind, some of + <application>pg_rewind</application>. After performing the rewind, some of those files may have been copied from the source, in which case it may - be necessary to remove the data copied and restore back the set of links - used before the rewind. + be necessary to remove them and restore the files removed beforehand. </para> </warning> </refsect1> @@ -183,7 +182,7 @@ PostgreSQL documentation <command>pg_rewind</command> to return without waiting, which is faster, but means that a subsequent operating system crash can leave the synchronized data folder corrupt. Generally, this option is - useful for testing but should not be used when creating a production + useful for testing but should not be used on a production installation. </para> </listitem> diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index f11d366..b4c7629 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -474,10 +474,8 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d </listitem> </itemizedlist> - Because in "prepared" mode <application>pgbench</application> reuses - the parse analysis result for the second and subsequent query - iteration, <application>pgbench</application> runs faster in the - prepared mode than in other modes. + <application>pgbench</application> runs faster in prepared mode because the + parse analysis happens only during the first query. </para> <para> The default is simple query protocol. (See <xref linkend="protocol"/> diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index e05a76c..a5a6eba 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -241,7 +241,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR <para> Reindexing a single index or table requires being the owner of that index or table. Reindexing a schema or database requires being the - owner of that schema or database. Note that is therefore sometimes + owner of that schema or database. Note specifically that it's possible for non-superusers to rebuild indexes of tables owned by other users. However, as a special exception, when <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command> diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index 419f753..79f5322 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -103,7 +103,7 @@ less -x4 message text. In addition there are optional elements, the most common of which is an error identifier code that follows the SQL spec's SQLSTATE conventions. - <function>ereport</function> itself is just a shell function, that exists + <function>ereport</function> itself is just a shell function that exists mainly for the syntactic convenience of making message generation look like a function call in the C source code. The only parameter accepted directly by <function>ereport</function> is the severity level. @@ -359,7 +359,7 @@ ereport(ERROR, specify suppression of the <literal>CONTEXT:</literal> portion of a message in the postmaster log. This should only be used for verbose debugging messages where the repeated inclusion of context would bloat the log - volume too much. + too much. </para> </listitem> </itemizedlist> @@ -452,8 +452,8 @@ Hint: the addendum enough for error messages. Detail and hint messages can be relegated to a verbose mode, or perhaps a pop-up error-details window. Also, details and hints would normally be suppressed from the server log to save - space. Reference to implementation details is best avoided since users - aren't expected to know the details. + space. References to implementation details are best avoided since users + aren't expected to know them. </para> </simplesect> @@ -504,14 +504,14 @@ Hint: the addendum <title>Use of Quotes</title> <para> - Use quotes always to delimit file names, user-supplied identifiers, and + Always use quotes to delimit file names, user-supplied identifiers, and other variables that might contain words. Do not use them to mark up variables that will not contain words (for example, operator names). </para> <para> There are functions in the backend that will double-quote their own output - at need (for example, <function>format_type_be()</function>). Do not put + as needed (for example, <function>format_type_be()</function>). Do not put additional quotes around the output of such functions. </para> @@ -872,7 +872,7 @@ BETTER: unrecognized node type: 42 from a few platform dependent pieces. </para> <para> - A few features included in the C99 standard are, at this time, not be + A few features included in the C99 standard are, at this time, not permitted to be used in core <productname>PostgreSQL</productname> code. This currently includes variable length arrays, intermingled declarations and code, <literal>//</literal> comments, universal @@ -880,16 +880,16 @@ BETTER: unrecognized node type: 42 practices. </para> <para> - Features from later revision of the C standard or compiler specific + Features from later revisions of the C standard or compiler specific features can be used, if a fallback is provided. </para> <para> - For example <literal>_StaticAssert()</literal> and + For example, <literal>_StaticAssert()</literal> and <literal>__builtin_constant_p</literal> are currently used, even though - they are from newer revisions of the C standard and a - <productname>GCC</productname> extension respectively. If not available - we respectively fall back to using a C99 compatible replacement that - performs the same checks, but emits rather cryptic messages and do not + they are from a newer revision of the C standard and a + <productname>GCC</productname> extension, respectively. If not available, in the first case, + we fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages; in the second case, we do not use <literal>__builtin_constant_p</literal>. </para> </simplesect> @@ -897,14 +897,14 @@ BETTER: unrecognized node type: 42 <simplesect> <title>Function-Like Macros and Inline Functions</title> <para> - Both, macros with arguments and <literal>static inline</literal> - functions, may be used. The latter are preferable if there are + Both macros with arguments and <literal>static inline</literal> + functions may be used. The latter are preferable if there are multiple-evaluation hazards when written as a macro, as e.g. the case with <programlisting> #define Max(x, y) ((x) > (y) ? (x) : (y)) </programlisting> - or when the macro would be very long. In other cases it's only + or when the macro would be very long. In other cases, it's only possible to use macros, or at least easier. For example because expressions of various types need to be passed to the macro. </para> @@ -936,19 +936,19 @@ MemoryContextSwitchTo(MemoryContext context) <simplesect> <title>Writing Signal Handlers</title> <para> - To be suitable to run inside a signal handler code has to be + To be suitable to run inside a signal handler, code has to be written very carefully. The fundamental problem is that, unless blocked, a signal handler can interrupt code at any time. If code - inside the signal handler uses the same state as code outside - chaos may ensue. As an example consider what happens if a signal + inside the signal handler uses the same state as code outside, + chaos may ensue. As an example, consider what happens if a signal handler tries to acquire a lock that's already held in the interrupted code. </para> <para> - Barring special arrangements code in signal handlers may only + Barring special arrangements, code in signal handlers may only call async-signal safe functions (as defined in POSIX) and access variables of type <literal>volatile sig_atomic_t</literal>. A few - functions in <command>postgres</command> are also deemed signal safe, importantly + functions in <command>postgres</command> are also deemed signal safe; specifically, <function>SetLatch()</function>. </para> <para> @@ -969,9 +969,9 @@ handle_sighup(SIGNAL_ARGS) } </programlisting> <varname>errno</varname> is saved and restored because - <function>SetLatch()</function> might change it. If that were not done - interrupted code that's currently inspecting <varname>errno</varname> might see the wrong - value. + <function>SetLatch()</function> might change it. If that were not done, + code interrupted by a signal might see the wrong value of + <varname>errno</varname>. </para> </simplesect> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 3403269..5c17b10 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3364,11 +3364,11 @@ if (!ptr) </indexterm> <para> - By default, a function is just a <quote>black box</quote> that the - database system knows very little about the behavior of. However, - that means that queries using the function may be executed much less + By default, a function is a <quote>black box</quote> that the + database system knows very little about, which + means queries calling the function may be executed less efficiently than they could be. It is possible to supply additional - knowledge that helps the planner optimize function calls. + information that helps the planner optimize function calls. </para> <para> @@ -3381,7 +3381,7 @@ if (!ptr) The parallel safety property (<literal>PARALLEL UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or <literal>PARALLEL SAFE</literal>) must also be specified if you hope - to use the function in parallelized queries. + queries calling the function to use parallel query. It can also be useful to specify the function's estimated execution cost, and/or the number of rows a set-returning function is estimated to return. However, the declarative way of specifying those two @@ -3393,7 +3393,7 @@ if (!ptr) It is also possible to attach a <firstterm>planner support function</firstterm> to a SQL-callable function (called its <firstterm>target function</firstterm>), and thereby provide - knowledge about the target function that is too complex to be + information about the target function that is too complex to be represented declaratively. Planner support functions have to be written in C (although their target functions might not be), so this is an advanced feature that relatively few people will use. -- 2.1.4 --IMjqdzrDRly81ofr Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0003-JIT-typos.patch" ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 02/12] review docs for pg12dev @ 2019-03-28 23:50 Justin Pryzby <pryzbyj@telsasoft.com> 0 siblings, 0 replies; 132+ messages in thread From: Justin Pryzby @ 2019-03-28 23:50 UTC (permalink / raw) --- doc/src/sgml/bloom.sgml | 2 +- doc/src/sgml/catalogs.sgml | 4 ++-- doc/src/sgml/config.sgml | 13 ++++++----- doc/src/sgml/ecpg.sgml | 18 +++++++------- doc/src/sgml/libpq.sgml | 2 +- doc/src/sgml/monitoring.sgml | 34 +++++++++++++-------------- doc/src/sgml/perform.sgml | 8 +++---- doc/src/sgml/ref/alter_table.sgml | 4 ++-- doc/src/sgml/ref/create_index.sgml | 4 ++-- doc/src/sgml/ref/pg_rewind.sgml | 17 +++++++------- doc/src/sgml/ref/pgbench.sgml | 6 ++--- doc/src/sgml/ref/reindex.sgml | 2 +- doc/src/sgml/runtime.sgml | 7 +++--- doc/src/sgml/sources.sgml | 48 +++++++++++++++++++------------------- doc/src/sgml/xfunc.sgml | 12 +++++----- src/bin/pg_upgrade/check.c | 6 ++--- 16 files changed, 92 insertions(+), 95 deletions(-) diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml index 6eeadde..c341b65 100644 --- a/doc/src/sgml/bloom.sgml +++ b/doc/src/sgml/bloom.sgml @@ -65,7 +65,7 @@ <para> Number of bits generated for each index column. Each parameter's name refers to the number of the index column that it controls. The default - is <literal>2</literal> bits and maximum is <literal>4095</literal>. Parameters for + is <literal>2</literal> bits and the maximum is <literal>4095</literal>. Parameters for index columns not actually used are ignored. </para> </listitem> diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 1701863..40ddec4 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -3052,7 +3052,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l simplifies <command>ATTACH/DETACH PARTITION</command> operations: the partition dependencies need only be added or removed. Example: a child partitioned index is made partition-dependent - on both the partition table it is on and the parent partitioned + on both the table partition and the parent partitioned index, so that it goes away if either of those is dropped, but not otherwise. The dependency on the parent index is primary, so that if the user tries to drop the child partitioned index, @@ -3115,7 +3115,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l Note that it's quite possible for two objects to be linked by more than one <structname>pg_depend</structname> entry. For example, a child partitioned index would have both a partition-type dependency on its - associated partition table, and an auto dependency on each column of + associated table partition, and an auto dependency on each column of that table that it indexes. This sort of situation expresses the union of multiple dependency semantics. A dependent object can be dropped without <literal>CASCADE</literal> if any of its dependencies satisfies diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index ad5a620..e45a321 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -112,7 +112,7 @@ For example, <literal>30.1 GB</literal> will be converted to <literal>30822 MB</literal> not <literal>32319628902 B</literal>. If the parameter is of integer type, a final rounding to integer - occurs after any units conversion. + occurs after any unit conversion. </para> </listitem> @@ -3433,7 +3433,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows current when the base backup was taken. The value <literal>latest</literal> recovers to the latest timeline found in the archive, which is useful in - a standby server. <literal>latest</literal> is the default. + a standby server. The default is <literal>latest</literal>. </para> <para> @@ -3540,7 +3540,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows servers or streaming base backup clients (i.e., the maximum number of simultaneously running WAL sender processes). The default is <literal>10</literal>. The value <literal>0</literal> means - replication is disabled. Abrupt streaming client disconnection might + replication is disabled. Abrupt disconnection of a streaming client might leave an orphaned connection slot behind until a timeout is reached, so this parameter should be set slightly higher than the maximum number of expected clients so disconnected clients can immediately @@ -4195,8 +4195,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class=" This parameter is intended for use with streaming replication deployments; however, if the parameter is specified it will be honored in all cases. - <varname>hot_standby_feedback</varname> will be delayed by use of this feature - which could lead to bloat on the master; use both together with care. + <varname>hot_standby_feedback</varname> will be delayed by use of this feature. + Combinining these settings could lead to bloat on the master, so should + be done only with care. <warning> <para> @@ -6941,7 +6942,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; <para> Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs - all autovacuum actions. Minus-one (the default) disables logging + all autovacuum actions. <literal>-1</literal> (the default) disables logging autovacuum actions. For example, if you set this to <literal>250ms</literal> then all automatic vacuums and analyzes that run 250ms or longer will be logged. In addition, when this parameter is diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index d5ee6a5..798aae4 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -662,7 +662,7 @@ EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>; not really useful in real applications. This section explains in detail how you can pass data between your C program and the embedded SQL statements using a simple mechanism called - <firstterm>host variables</firstterm>. In an embedded SQL program we + <firstterm>host variables</firstterm>. In an embedded SQL program we consider the SQL statements to be <firstterm>guests</firstterm> in the C program code which is the <firstterm>host language</firstterm>. Therefore the variables of the C program are called <firstterm>host @@ -979,7 +979,7 @@ EXEC SQL END DECLARE SECTION; <para> The other way is using the <type>VARCHAR</type> type, which is a - special type provided by ECPG. The definition on an array of + special type provided by ECPG. The definition of an array of type <type>VARCHAR</type> is converted into a named <type>struct</type> for every variable. A declaration like: <programlisting> @@ -989,7 +989,7 @@ VARCHAR var[180]; <programlisting> struct varchar_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts the string + The member <structfield>arr</structfield> stores the string including a terminating zero byte. Thus, to store a string in a <type>VARCHAR</type> host variable, the host variable has to be declared with the length including the zero byte terminator. The @@ -1209,8 +1209,8 @@ EXEC SQL END DECLARE SECTION; <title id="ecpg-type-bytea">bytea</title> <para> - The handling of the <type>bytea</type> type is also similar to - the <type>VARCHAR</type>. The definition on an array of type + The handling of the <type>bytea</type> type is similar to + the <type>VARCHAR</type>. The definition of an array of type <type>bytea</type> is converted into a named struct for every variable. A declaration like: <programlisting> @@ -1220,9 +1220,8 @@ bytea var[180]; <programlisting> struct bytea_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts binary format - data. It also can handle even <literal>'\0'</literal> as part of - data unlike <type>VARCHAR</type>. + The member <structfield>arr</structfield> stores binary format + data, which can include zero bytes, unlike <type>VARCHAR</type>. The data is converted from/to hex format and sent/received by ecpglib. </para> @@ -7571,8 +7570,7 @@ PREPARE <replaceable class="parameter">name</replaceable> FROM <replaceable clas <listitem> <para> A literal C string or a host variable containing a preparable - statement, one of the SELECT, INSERT, UPDATE, or - DELETE. + statement (SELECT, INSERT, UPDATE, or DELETE). </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index fe833aa..c8e6919 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1122,7 +1122,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname <term><literal>connect_timeout</literal></term> <listitem> <para> - Maximum wait for connection, in seconds (write as a decimal integer, + Maximum time to wait while connecting, in seconds (write as a decimal integer, e.g. <literal>10</literal>). Zero, negative, or not specified means wait indefinitely. The minimum allowed timeout is 2 seconds, therefore a value of <literal>1</literal> is interpreted as <literal>2</literal>. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 4eb43f2..a1c3848 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -271,13 +271,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <para> Some of the information in the dynamic statistics views shown in <xref linkend="monitoring-stats-dynamic-views-table"/> is security restricted. - Ordinary users can only see all the information about their own sessions - (sessions belonging to a role that they are a member of). In rows about + Ordinary users can only see all information about their own sessions + (sessions belonging to a role of which they are a member). In rows for other sessions, many columns will be null. Note, however, that the existence of a session and its general properties such as its sessions user and database are visible to all users. Superusers and members of the built-in role <literal>pg_read_all_stats</literal> (see also <xref - linkend="default-roles"/>) can see all the information about all sessions. + linkend="default-roles"/>) can see all information about all sessions. </para> <table id="monitoring-stats-dynamic-views-table"> @@ -3631,9 +3631,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <entry> The index is being built by the access method-specific code. In this phase, access methods that support progress reporting fill in their own progress data, - and the subphase is indicated in this column. Typically, + and the subphase is indicated in this column. <structname>blocks_total</structname> and <structname>blocks_done</structname> - will contain progress data, as well as potentially + will contain progress data, as may <structname>tuples_total</structname> and <structname>tuples_done</structname>. </entry> </row> @@ -3718,16 +3718,16 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>VACUUM Progress Reporting</title> <para> - Whenever <command>VACUUM</command> is running, the - <structname>pg_stat_progress_vacuum</structname> view will contain - one row for each backend (including autovacuum worker processes) that is - currently vacuuming. The tables below describe the information + The <structname>pg_stat_progress_vacuum</structname> view will contain one + row for each backend that is running <command>VACUUM</command>, including + autovacuum worker processes. + The tables below describe the information that will be reported and provide information about how to interpret it. - Progress for <command>VACUUM FULL</command> commands is reported via - <structname>pg_stat_progress_cluster</structname> - because both <command>VACUUM FULL</command> and <command>CLUSTER</command> - rewrite the table, while regular <command>VACUUM</command> only modifies it - in place. See <xref linkend='cluster-progress-reporting'/>. + Progress for <command>VACUUM FULL</command> commands is instead reported via + <structname>pg_stat_progress_cluster</structname>, + because <command>VACUUM FULL</command> rewrites the table, like <command>CLUSTER</command>, + while regular <command>VACUUM</command> modifies it in place. See <xref linkend='cluster-progress-reporting'/>. + </para> <table id="pg-stat-progress-vacuum-view" xreflabel="pg_stat_progress_vacuum"> @@ -3910,9 +3910,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>CLUSTER Progress Reporting</title> <para> - Whenever <command>CLUSTER</command> or <command>VACUUM FULL</command> is - running, the <structname>pg_stat_progress_cluster</structname> view will - contain a row for each backend that is currently running either command. + The <structname>pg_stat_progress_cluster</structname> view will contain a + row for each backend that is running either + <command>CLUSTER</command> or <command>VACUUM FULL</command>. The tables below describe the information that will be reported and provide information about how to interpret it. </para> diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml index a84be85..65c161b 100644 --- a/doc/src/sgml/perform.sgml +++ b/doc/src/sgml/perform.sgml @@ -899,10 +899,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 Generally, the <command>EXPLAIN</command> output will display details for every plan node which was generated by the query planner. However, there are cases where the executor is able to determine that certain nodes are - not required; currently, the only node types to support this are the - <literal>Append</literal> and <literal>MergeAppend</literal> nodes. These - node types have the ability to discard subnodes which they are able to - determine won't contain any records required by the query. It is possible + not required; currently, the only node types to support this are + <literal>Append</literal> and <literal>MergeAppend</literal>, which + are able to discard subnodes when it's deduced that + they will not contain any records required by the query. It is possible to determine that nodes have been removed in this way by the presence of a "Subplans Removed" property in the <command>EXPLAIN</command> output. </para> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 49b081a..dd80bd0 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -219,7 +219,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM <para> <literal>SET NOT NULL</literal> may only be applied to a column - providing none of the records in the table contain a + provided none of the records in the table contain a <literal>NULL</literal> value for the column. Ordinarily this is checked during the <literal>ALTER TABLE</literal> by scanning the entire table; however, if a valid <literal>CHECK</literal> constraint is @@ -642,7 +642,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM When applied to a partitioned table, nothing is moved, but any partitions created afterwards with <command>CREATE TABLE PARTITION OF</command> will use that tablespace, - unless the <literal>TABLESPACE</literal> clause is used to override it. + unless overridden by its <literal>TABLESPACE</literal> clause. </para> <para> diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index d9d95b2..14a557a 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -181,8 +181,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= </para> <para> - Currently, the B-tree and the GiST index access methods supports this - feature. In B-tree and the GiST indexes, the values of columns listed + Currently, only the B-tree and GiST index access methods support this + feature. In B-tree and GiST indexes, the values of columns listed in the <literal>INCLUDE</literal> clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index e9715d5..68c1c4d 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -106,15 +106,14 @@ PostgreSQL documentation </para> <para> - <application>pg_rewind</application> will fail immediately if it finds - files it cannot write directly to. This can happen for example when - the source and the target server use the same file mapping for read-only - SSL keys and certificates. If such files are present on the target server + <application>pg_rewind</application> will fail immediately if it experiences + a write error. This can happen for example when + the source and target server use the same file mapping for read-only + SSL keys and certificates. If such files are present on the target server, it is recommended to remove them before running - <application>pg_rewind</application>. After doing the rewind, some of + <application>pg_rewind</application>. After performing the rewind, some of those files may have been copied from the source, in which case it may - be necessary to remove the data copied and restore back the set of links - used before the rewind. + be necessary to remove them and restore the files removed beforehand. </para> </warning> </refsect1> @@ -185,7 +184,7 @@ PostgreSQL documentation <command>pg_rewind</command> to return without waiting, which is faster, but means that a subsequent operating system crash can leave the synchronized data folder corrupt. Generally, this option is - useful for testing but should not be used when creating a production + useful for testing but should not be used on a production installation. </para> </listitem> @@ -266,7 +265,7 @@ GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, b <para> When executing <application>pg_rewind</application> using an online cluster as source which has been recently promoted, it is necessary - to execute a <command>CHECKPOINT</command> after promotion so as its + to execute a <command>CHECKPOINT</command> after promotion such that its control file reflects up-to-date timeline information, which is used by <application>pg_rewind</application> to check if the target cluster can be rewound using the designated source cluster. diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index ee2501b..7d3cf25 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -474,10 +474,8 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d </listitem> </itemizedlist> - Because in "prepared" mode <application>pgbench</application> reuses - the parse analysis result for the second and subsequent query - iteration, <application>pgbench</application> runs faster in the - prepared mode than in other modes. + <application>pgbench</application> runs faster in prepared mode because the + parse analysis happens only during the first query. </para> <para> The default is simple query protocol. (See <xref linkend="protocol"/> diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index e05a76c..a5a6eba 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -241,7 +241,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR <para> Reindexing a single index or table requires being the owner of that index or table. Reindexing a schema or database requires being the - owner of that schema or database. Note that is therefore sometimes + owner of that schema or database. Note specifically that it's possible for non-superusers to rebuild indexes of tables owned by other users. However, as a special exception, when <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command> diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index fde9dbc..032553a 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -2601,8 +2601,9 @@ openssl x509 -req -in server.csr -text -days 365 \ using <acronym>GSSAPI</acronym> to encrypt client/server communications for increased security. Support requires that a <acronym>GSSAPI</acronym> implementation (such as MIT krb5) is installed on both client and server - systems, and that support in <productname>PostgreSQL</productname> is - enabled at build time (see <xref linkend="installation"/>). + systems, and must be enabled at the time + <productname>PostgreSQL</productname> is built (see <xref + linkend="installation"/>). </para> <sect2 id="gssapi-setup"> @@ -2611,7 +2612,7 @@ openssl x509 -req -in server.csr -text -days 365 \ <para> The <productname>PostgreSQL</productname> server will listen for both normal and <acronym>GSSAPI</acronym>-encrypted connections on the same TCP - port, and will negotiate with any connecting client on whether to + port, and will negotiate with any connecting client whether to use <acronym>GSSAPI</acronym> for encryption (and for authentication). By default, this decision is up to the client (which means it can be downgraded by an attacker); see <xref linkend="auth-pg-hba-conf"/> about diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index 419f753..79f5322 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -103,7 +103,7 @@ less -x4 message text. In addition there are optional elements, the most common of which is an error identifier code that follows the SQL spec's SQLSTATE conventions. - <function>ereport</function> itself is just a shell function, that exists + <function>ereport</function> itself is just a shell function that exists mainly for the syntactic convenience of making message generation look like a function call in the C source code. The only parameter accepted directly by <function>ereport</function> is the severity level. @@ -359,7 +359,7 @@ ereport(ERROR, specify suppression of the <literal>CONTEXT:</literal> portion of a message in the postmaster log. This should only be used for verbose debugging messages where the repeated inclusion of context would bloat the log - volume too much. + too much. </para> </listitem> </itemizedlist> @@ -452,8 +452,8 @@ Hint: the addendum enough for error messages. Detail and hint messages can be relegated to a verbose mode, or perhaps a pop-up error-details window. Also, details and hints would normally be suppressed from the server log to save - space. Reference to implementation details is best avoided since users - aren't expected to know the details. + space. References to implementation details are best avoided since users + aren't expected to know them. </para> </simplesect> @@ -504,14 +504,14 @@ Hint: the addendum <title>Use of Quotes</title> <para> - Use quotes always to delimit file names, user-supplied identifiers, and + Always use quotes to delimit file names, user-supplied identifiers, and other variables that might contain words. Do not use them to mark up variables that will not contain words (for example, operator names). </para> <para> There are functions in the backend that will double-quote their own output - at need (for example, <function>format_type_be()</function>). Do not put + as needed (for example, <function>format_type_be()</function>). Do not put additional quotes around the output of such functions. </para> @@ -872,7 +872,7 @@ BETTER: unrecognized node type: 42 from a few platform dependent pieces. </para> <para> - A few features included in the C99 standard are, at this time, not be + A few features included in the C99 standard are, at this time, not permitted to be used in core <productname>PostgreSQL</productname> code. This currently includes variable length arrays, intermingled declarations and code, <literal>//</literal> comments, universal @@ -880,16 +880,16 @@ BETTER: unrecognized node type: 42 practices. </para> <para> - Features from later revision of the C standard or compiler specific + Features from later revisions of the C standard or compiler specific features can be used, if a fallback is provided. </para> <para> - For example <literal>_StaticAssert()</literal> and + For example, <literal>_StaticAssert()</literal> and <literal>__builtin_constant_p</literal> are currently used, even though - they are from newer revisions of the C standard and a - <productname>GCC</productname> extension respectively. If not available - we respectively fall back to using a C99 compatible replacement that - performs the same checks, but emits rather cryptic messages and do not + they are from a newer revision of the C standard and a + <productname>GCC</productname> extension, respectively. If not available, in the first case, + we fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages; in the second case, we do not use <literal>__builtin_constant_p</literal>. </para> </simplesect> @@ -897,14 +897,14 @@ BETTER: unrecognized node type: 42 <simplesect> <title>Function-Like Macros and Inline Functions</title> <para> - Both, macros with arguments and <literal>static inline</literal> - functions, may be used. The latter are preferable if there are + Both macros with arguments and <literal>static inline</literal> + functions may be used. The latter are preferable if there are multiple-evaluation hazards when written as a macro, as e.g. the case with <programlisting> #define Max(x, y) ((x) > (y) ? (x) : (y)) </programlisting> - or when the macro would be very long. In other cases it's only + or when the macro would be very long. In other cases, it's only possible to use macros, or at least easier. For example because expressions of various types need to be passed to the macro. </para> @@ -936,19 +936,19 @@ MemoryContextSwitchTo(MemoryContext context) <simplesect> <title>Writing Signal Handlers</title> <para> - To be suitable to run inside a signal handler code has to be + To be suitable to run inside a signal handler, code has to be written very carefully. The fundamental problem is that, unless blocked, a signal handler can interrupt code at any time. If code - inside the signal handler uses the same state as code outside - chaos may ensue. As an example consider what happens if a signal + inside the signal handler uses the same state as code outside, + chaos may ensue. As an example, consider what happens if a signal handler tries to acquire a lock that's already held in the interrupted code. </para> <para> - Barring special arrangements code in signal handlers may only + Barring special arrangements, code in signal handlers may only call async-signal safe functions (as defined in POSIX) and access variables of type <literal>volatile sig_atomic_t</literal>. A few - functions in <command>postgres</command> are also deemed signal safe, importantly + functions in <command>postgres</command> are also deemed signal safe; specifically, <function>SetLatch()</function>. </para> <para> @@ -969,9 +969,9 @@ handle_sighup(SIGNAL_ARGS) } </programlisting> <varname>errno</varname> is saved and restored because - <function>SetLatch()</function> might change it. If that were not done - interrupted code that's currently inspecting <varname>errno</varname> might see the wrong - value. + <function>SetLatch()</function> might change it. If that were not done, + code interrupted by a signal might see the wrong value of + <varname>errno</varname>. </para> </simplesect> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 3403269..5c17b10 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3364,11 +3364,11 @@ if (!ptr) </indexterm> <para> - By default, a function is just a <quote>black box</quote> that the - database system knows very little about the behavior of. However, - that means that queries using the function may be executed much less + By default, a function is a <quote>black box</quote> that the + database system knows very little about, which + means queries calling the function may be executed less efficiently than they could be. It is possible to supply additional - knowledge that helps the planner optimize function calls. + information that helps the planner optimize function calls. </para> <para> @@ -3381,7 +3381,7 @@ if (!ptr) The parallel safety property (<literal>PARALLEL UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or <literal>PARALLEL SAFE</literal>) must also be specified if you hope - to use the function in parallelized queries. + queries calling the function to use parallel query. It can also be useful to specify the function's estimated execution cost, and/or the number of rows a set-returning function is estimated to return. However, the declarative way of specifying those two @@ -3393,7 +3393,7 @@ if (!ptr) It is also possible to attach a <firstterm>planner support function</firstterm> to a SQL-callable function (called its <firstterm>target function</firstterm>), and thereby provide - knowledge about the target function that is too complex to be + information about the target function that is too complex to be represented declaratively. Planner support functions have to be written in C (although their target functions might not be), so this is an advanced feature that relatively few people will use. diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index fc5aa70..04c9ed8 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -222,13 +222,13 @@ output_completion_banner(char *analyze_script_file_name, /* Did we copy the free space files? */ if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) pg_log(PG_REPORT, - "Optimizer statistics are not transferred by pg_upgrade so,\n" - "once you start the new server, consider running:\n" + "Optimizer statistics are not transferred by pg_upgrade.\n" + "Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); else pg_log(PG_REPORT, "Optimizer statistics and free space information are not transferred\n" - "by pg_upgrade so, once you start the new server, consider running:\n" + "by pg_upgrade. Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); -- 2.1.4 --u65IjBhB3TIa72Vp Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v2-0003-JIT-typos.patch" ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 01/12] review docs for pg12dev @ 2019-03-28 23:50 Justin Pryzby <pryzbyj@telsasoft.com> 0 siblings, 0 replies; 132+ messages in thread From: Justin Pryzby @ 2019-03-28 23:50 UTC (permalink / raw) --- doc/src/sgml/bloom.sgml | 2 +- doc/src/sgml/catalogs.sgml | 4 ++-- doc/src/sgml/config.sgml | 15 +++++++------ doc/src/sgml/ddl.sgml | 8 +++---- doc/src/sgml/ecpg.sgml | 16 ++++++-------- doc/src/sgml/libpq.sgml | 2 +- doc/src/sgml/monitoring.sgml | 44 +++++++++++++++++++------------------- doc/src/sgml/perform.sgml | 8 +++---- doc/src/sgml/protocol.sgml | 6 +++--- doc/src/sgml/ref/alter_table.sgml | 4 ++-- doc/src/sgml/ref/create_index.sgml | 4 ++-- doc/src/sgml/ref/pg_rewind.sgml | 17 +++++++-------- doc/src/sgml/ref/pgbench.sgml | 6 ++---- doc/src/sgml/ref/reindex.sgml | 2 +- doc/src/sgml/runtime.sgml | 7 +++--- doc/src/sgml/sources.sgml | 36 +++++++++++++++---------------- doc/src/sgml/xfunc.sgml | 12 +++++------ src/bin/pg_upgrade/check.c | 6 +++--- 18 files changed, 98 insertions(+), 101 deletions(-) diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml index 6eeadde..c341b65 100644 --- a/doc/src/sgml/bloom.sgml +++ b/doc/src/sgml/bloom.sgml @@ -65,7 +65,7 @@ <para> Number of bits generated for each index column. Each parameter's name refers to the number of the index column that it controls. The default - is <literal>2</literal> bits and maximum is <literal>4095</literal>. Parameters for + is <literal>2</literal> bits and the maximum is <literal>4095</literal>. Parameters for index columns not actually used are ignored. </para> </listitem> diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 4c7e938..d544e60 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -3052,7 +3052,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l simplifies <command>ATTACH/DETACH PARTITION</command> operations: the partition dependencies need only be added or removed. Example: a child partitioned index is made partition-dependent - on both the partition table it is on and the parent partitioned + on both the table partition and the parent partitioned index, so that it goes away if either of those is dropped, but not otherwise. The dependency on the parent index is primary, so that if the user tries to drop the child partitioned index, @@ -3115,7 +3115,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l Note that it's quite possible for two objects to be linked by more than one <structname>pg_depend</structname> entry. For example, a child partitioned index would have both a partition-type dependency on its - associated partition table, and an auto dependency on each column of + associated table partition, and an auto dependency on each column of that table that it indexes. This sort of situation expresses the union of multiple dependency semantics. A dependent object can be dropped without <literal>CASCADE</literal> if any of its dependencies satisfies diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 36062c3..73eb768 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -112,7 +112,7 @@ For example, <literal>30.1 GB</literal> will be converted to <literal>30822 MB</literal> not <literal>32319628902 B</literal>. If the parameter is of integer type, a final rounding to integer - occurs after any units conversion. + occurs after any unit conversion. </para> </listitem> @@ -3433,7 +3433,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows current when the base backup was taken. The value <literal>latest</literal> recovers to the latest timeline found in the archive, which is useful in - a standby server. <literal>latest</literal> is the default. + a standby server. The default is <literal>latest</literal>. </para> <para> @@ -3540,7 +3540,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows servers or streaming base backup clients (i.e., the maximum number of simultaneously running WAL sender processes). The default is <literal>10</literal>. The value <literal>0</literal> means - replication is disabled. Abrupt streaming client disconnection might + replication is disabled. Abrupt disconnection of a streaming client might leave an orphaned connection slot behind until a timeout is reached, so this parameter should be set slightly higher than the maximum number of expected clients so disconnected clients can immediately @@ -4195,8 +4195,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class=" This parameter is intended for use with streaming replication deployments; however, if the parameter is specified it will be honored in all cases. - <varname>hot_standby_feedback</varname> will be delayed by use of this feature - which could lead to bloat on the master; use both together with care. + <varname>hot_standby_feedback</varname> will be delayed by use of this feature. + Combinining these settings could lead to bloat on the master, so should + be done only with care. <warning> <para> @@ -6947,8 +6948,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; <para> Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs - all autovacuum actions. <literal>-1</literal> (the default) disables - logging autovacuum actions. For example, if you set this to + all autovacuum actions. <literal>-1</literal> (the default) disables logging + autovacuum actions. For example, if you set this to <literal>250ms</literal> then all automatic vacuums and analyzes that run 250ms or longer will be logged. In addition, when this parameter is set to any value other than <literal>-1</literal>, a message will be diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index a0a7435..cfe83a8 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -3867,12 +3867,12 @@ CREATE INDEX ON measurement (logdate); <para> Normally the set of partitions established when initially defining the - table are not intended to remain static. It is common to want to - remove old partitions of data and periodically add new partitions for + table are not intended to remain static. It's common to + remove partitions of old data and add partitions for new data. One of the most important advantages of partitioning is - precisely that it allows this otherwise painful task to be executed + allowing this otherwise painful task to be executed nearly instantaneously by manipulating the partition structure, rather - than physically moving large amounts of data around. + than physically moving around large amounts of data. </para> <para> diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index 6641eee..d2dd96c 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -979,7 +979,7 @@ EXEC SQL END DECLARE SECTION; <para> The other way is using the <type>VARCHAR</type> type, which is a - special type provided by ECPG. The definition on an array of + special type provided by ECPG. The definition of an array of type <type>VARCHAR</type> is converted into a named <type>struct</type> for every variable. A declaration like: <programlisting> @@ -989,7 +989,7 @@ VARCHAR var[180]; <programlisting> struct varchar_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts the string + The member <structfield>arr</structfield> stores the string including a terminating zero byte. Thus, to store a string in a <type>VARCHAR</type> host variable, the host variable has to be declared with the length including the zero byte terminator. The @@ -1209,8 +1209,8 @@ EXEC SQL END DECLARE SECTION; <title id="ecpg-type-bytea">bytea</title> <para> - The handling of the <type>bytea</type> type is also similar to - the <type>VARCHAR</type>. The definition on an array of type + The handling of the <type>bytea</type> type is similar to + the <type>VARCHAR</type>. The definition of an array of type <type>bytea</type> is converted into a named struct for every variable. A declaration like: <programlisting> @@ -1220,9 +1220,8 @@ bytea var[180]; <programlisting> struct bytea_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts binary format - data. It also can handle even <literal>'\0'</literal> as part of - data unlike <type>VARCHAR</type>. + The member <structfield>arr</structfield> stores binary format + data, which can include zero bytes, unlike <type>VARCHAR</type>. The data is converted from/to hex format and sent/received by ecpglib. </para> @@ -7571,8 +7570,7 @@ PREPARE <replaceable class="parameter">name</replaceable> FROM <replaceable clas <listitem> <para> A literal C string or a host variable containing a preparable - statement, one of the SELECT, INSERT, UPDATE, or - DELETE. + statement (SELECT, INSERT, UPDATE, or DELETE). </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 7f01fcc..8a8427f 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1122,7 +1122,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname <term><literal>connect_timeout</literal></term> <listitem> <para> - Maximum wait for connection, in seconds (write as a decimal integer, + Maximum time to wait while connecting, in seconds (write as a decimal integer, e.g. <literal>10</literal>). Zero, negative, or not specified means wait indefinitely. The minimum allowed timeout is 2 seconds, therefore a value of <literal>1</literal> is interpreted as <literal>2</literal>. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index a179d61..6c98596 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -271,13 +271,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <para> Some of the information in the dynamic statistics views shown in <xref linkend="monitoring-stats-dynamic-views-table"/> is security restricted. - Ordinary users can only see all the information about their own sessions - (sessions belonging to a role that they are a member of). In rows about + Ordinary users can only see all information about their own sessions + (sessions belonging to a role of which they are a member). In rows for other sessions, many columns will be null. Note, however, that the existence of a session and its general properties such as its sessions user and database are visible to all users. Superusers and members of the built-in role <literal>pg_read_all_stats</literal> (see also <xref - linkend="default-roles"/>) can see all the information about all sessions. + linkend="default-roles"/>) can see all information about all sessions. </para> <table id="monitoring-stats-dynamic-views-table"> @@ -2504,14 +2504,14 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i <row> <entry><structfield>datname</structfield></entry> <entry><type>name</type></entry> - <entry>Name of this database, or <literal>NULL</literal> for the shared + <entry>Name of this database, or <literal>NULL</literal> for shared objects.</entry> </row> <row> <entry><structfield>numbackends</structfield></entry> <entry><type>integer</type></entry> <entry>Number of backends currently connected to this database, or - <literal>NULL</literal> for the shared objects. This is the only column + <literal>NULL</literal> for shared objects. This is the only column in this view that returns a value reflecting current state; all other columns return the accumulated values since the last reset.</entry> </row> @@ -2633,7 +2633,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i <para> The <structname>pg_stat_database</structname> view will contain one row - for each database in the cluster, plus one for the shared objects, showing + for each database in the cluster, plus one for shared objects, showing database-wide statistics. </para> @@ -3594,16 +3594,16 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <entry><structfield>partitions_total</structfield></entry> <entry><type>bigint</type></entry> <entry> - When creating an index on a partitioned table, this column is set to - the total number of partitions on which the index is to be created. + When creating an index on a partitioned table, this is + the total number of partitions to be processed. </entry> </row> <row> <entry><structfield>partitions_done</structfield></entry> <entry><type>bigint</type></entry> <entry> - When creating an index on a partitioned table, this column is set to - the number of partitions on which the index has been completed. + When creating an index on a partitioned table, this is + the number of partitions for which the process is complete. </entry> </row> </tbody> @@ -3643,9 +3643,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <entry> The index is being built by the access method-specific code. In this phase, access methods that support progress reporting fill in their own progress data, - and the subphase is indicated in this column. Typically, + and the subphase is indicated in this column. <structname>blocks_total</structname> and <structname>blocks_done</structname> - will contain progress data, as well as potentially + will contain progress data, as may <structname>tuples_total</structname> and <structname>tuples_done</structname>. </entry> </row> @@ -3730,15 +3730,15 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>VACUUM Progress Reporting</title> <para> - Whenever <command>VACUUM</command> is running, the - <structname>pg_stat_progress_vacuum</structname> view will contain - one row for each backend (including autovacuum worker processes) that is - currently vacuuming. The tables below describe the information + The <structname>pg_stat_progress_vacuum</structname> view will contain one + row for each backend that is running <command>VACUUM</command>, including + autovacuum worker processes. + The tables below describe the information that will be reported and provide information about how to interpret it. Progress for <command>VACUUM FULL</command> commands is reported via - <structname>pg_stat_progress_cluster</structname> - because both <command>VACUUM FULL</command> and <command>CLUSTER</command> - rewrite the table, while regular <command>VACUUM</command> only modifies it + <structname>pg_stat_progress_cluster</structname>, + because <command>VACUUM FULL</command> rewrites the table, like <command>CLUSTER</command>, + while regular <command>VACUUM</command> only modifies it in place. See <xref linkend='cluster-progress-reporting'/>. </para> @@ -3922,9 +3922,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>CLUSTER Progress Reporting</title> <para> - Whenever <command>CLUSTER</command> or <command>VACUUM FULL</command> is - running, the <structname>pg_stat_progress_cluster</structname> view will - contain a row for each backend that is currently running either command. + The <structname>pg_stat_progress_cluster</structname> view will contain a + row for each backend that is running either + <command>CLUSTER</command> or <command>VACUUM FULL</command>. The tables below describe the information that will be reported and provide information about how to interpret it. </para> diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml index a84be85..65c161b 100644 --- a/doc/src/sgml/perform.sgml +++ b/doc/src/sgml/perform.sgml @@ -899,10 +899,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 Generally, the <command>EXPLAIN</command> output will display details for every plan node which was generated by the query planner. However, there are cases where the executor is able to determine that certain nodes are - not required; currently, the only node types to support this are the - <literal>Append</literal> and <literal>MergeAppend</literal> nodes. These - node types have the ability to discard subnodes which they are able to - determine won't contain any records required by the query. It is possible + not required; currently, the only node types to support this are + <literal>Append</literal> and <literal>MergeAppend</literal>, which + are able to discard subnodes when it's deduced that + they will not contain any records required by the query. It is possible to determine that nodes have been removed in this way by the presence of a "Subplans Removed" property in the <command>EXPLAIN</command> output. </para> diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index b20f169..70f7286 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -1515,7 +1515,7 @@ SELECT 1/0; the server will only accept encrypted packets from the client which are less than 16kB; <function>gss_wrap_size_limit()</function> should be used by the client to determine the size of the unencrypted message which will fit - within this limit and larger messages should be broken up into multiple + within this limit; larger messages should be broken up into multiple <function>gss_wrap()</function> calls. Typical segments are 8kB of unencrypted data, resulting in encrypted packets of slightly larger than 8kB but well within the 16kB maximum. The server can be expected to not send @@ -1531,8 +1531,8 @@ SELECT 1/0; support to <productname>PostgreSQL</productname>. In this case the connection must be closed, but the frontend might choose to open a fresh connection and proceed without requesting <acronym>GSSAPI</acronym> - encryption. Given the length limits specified above, the ErrorMessage can - not be confused with a proper response from the server with an appropriate + encryption. Given the length limits specified above, the ErrorMessage + cannot be confused with a proper response from the server with an appropriate length. </para> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 49b081a..dd80bd0 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -219,7 +219,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM <para> <literal>SET NOT NULL</literal> may only be applied to a column - providing none of the records in the table contain a + provided none of the records in the table contain a <literal>NULL</literal> value for the column. Ordinarily this is checked during the <literal>ALTER TABLE</literal> by scanning the entire table; however, if a valid <literal>CHECK</literal> constraint is @@ -642,7 +642,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM When applied to a partitioned table, nothing is moved, but any partitions created afterwards with <command>CREATE TABLE PARTITION OF</command> will use that tablespace, - unless the <literal>TABLESPACE</literal> clause is used to override it. + unless overridden by its <literal>TABLESPACE</literal> clause. </para> <para> diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 30bb38b..bf4f550 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -181,8 +181,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= </para> <para> - Currently, the B-tree and the GiST index access methods support this - feature. In B-tree and the GiST indexes, the values of columns listed + Currently, only the B-tree and GiST index access methods support this + feature. In B-tree and GiST indexes, the values of columns listed in the <literal>INCLUDE</literal> clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index 4d91eeb..6f6d220 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -106,15 +106,14 @@ PostgreSQL documentation </para> <para> - <application>pg_rewind</application> will fail immediately if it finds - files it cannot write directly to. This can happen for example when - the source and the target server use the same file mapping for read-only - SSL keys and certificates. If such files are present on the target server + <application>pg_rewind</application> will fail immediately if it experiences + a write error. This can happen for example when + the source and target server use the same file mapping for read-only + SSL keys and certificates. If such files are present on the target server, it is recommended to remove them before running - <application>pg_rewind</application>. After doing the rewind, some of + <application>pg_rewind</application>. After performing the rewind, some of those files may have been copied from the source, in which case it may - be necessary to remove the data copied and restore back the set of links - used before the rewind. + be necessary to remove them and restore the files removed beforehand. </para> </warning> </refsect1> @@ -185,7 +184,7 @@ PostgreSQL documentation <command>pg_rewind</command> to return without waiting, which is faster, but means that a subsequent operating system crash can leave the synchronized data folder corrupt. Generally, this option is - useful for testing but should not be used when creating a production + useful for testing but should not be used on a production installation. </para> </listitem> @@ -266,7 +265,7 @@ GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, b <para> When executing <application>pg_rewind</application> using an online cluster as source which has been recently promoted, it is necessary - to execute a <command>CHECKPOINT</command> after promotion so as its + to execute a <command>CHECKPOINT</command> after promotion such that its control file reflects up-to-date timeline information, which is used by <application>pg_rewind</application> to check if the target cluster can be rewound using the designated source cluster. diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index ef22a48..7e8fc19 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -474,10 +474,8 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d </listitem> </itemizedlist> - Because in "prepared" mode <application>pgbench</application> reuses - the parse analysis result for the second and subsequent query - iteration, <application>pgbench</application> runs faster in the - prepared mode than in other modes. + <application>pgbench</application> runs faster in prepared mode because the + parse analysis happens only during the first query. </para> <para> The default is simple query protocol. (See <xref linkend="protocol"/> diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 303436c..5a1f634 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -240,7 +240,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR <para> Reindexing a single index or table requires being the owner of that index or table. Reindexing a schema or database requires being the - owner of that schema or database. Note that is therefore sometimes + owner of that schema or database. Note specifically that it's possible for non-superusers to rebuild indexes of tables owned by other users. However, as a special exception, when <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command> diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index e053e2e..798da30 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -2634,8 +2634,9 @@ openssl x509 -req -in server.csr -text -days 365 \ using <acronym>GSSAPI</acronym> to encrypt client/server communications for increased security. Support requires that a <acronym>GSSAPI</acronym> implementation (such as MIT krb5) is installed on both client and server - systems, and that support in <productname>PostgreSQL</productname> is - enabled at build time (see <xref linkend="installation"/>). + systems, and must be enabled at the time + <productname>PostgreSQL</productname> is built (see <xref + linkend="installation"/>). </para> <sect2 id="gssapi-setup"> @@ -2644,7 +2645,7 @@ openssl x509 -req -in server.csr -text -days 365 \ <para> The <productname>PostgreSQL</productname> server will listen for both normal and <acronym>GSSAPI</acronym>-encrypted connections on the same TCP - port, and will negotiate with any connecting client on whether to + port, and will negotiate with any connecting client whether to use <acronym>GSSAPI</acronym> for encryption (and for authentication). By default, this decision is up to the client (which means it can be downgraded by an attacker); see <xref linkend="auth-pg-hba-conf"/> about diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index a339ebb..2b9f59d 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -103,7 +103,7 @@ less -x4 message text. In addition there are optional elements, the most common of which is an error identifier code that follows the SQL spec's SQLSTATE conventions. - <function>ereport</function> itself is just a shell function, that exists + <function>ereport</function> itself is just a shell function that exists mainly for the syntactic convenience of making message generation look like a function call in the C source code. The only parameter accepted directly by <function>ereport</function> is the severity level. @@ -359,7 +359,7 @@ ereport(ERROR, specify suppression of the <literal>CONTEXT:</literal> portion of a message in the postmaster log. This should only be used for verbose debugging messages where the repeated inclusion of context would bloat the log - volume too much. + too much. </para> </listitem> </itemizedlist> @@ -452,8 +452,8 @@ Hint: the addendum enough for error messages. Detail and hint messages can be relegated to a verbose mode, or perhaps a pop-up error-details window. Also, details and hints would normally be suppressed from the server log to save - space. Reference to implementation details is best avoided since users - aren't expected to know the details. + space. References to implementation details are best avoided since users + aren't expected to know them. </para> </simplesect> @@ -504,14 +504,14 @@ Hint: the addendum <title>Use of Quotes</title> <para> - Use quotes always to delimit file names, user-supplied identifiers, and + Always use quotes to delimit file names, user-supplied identifiers, and other variables that might contain words. Do not use them to mark up variables that will not contain words (for example, operator names). </para> <para> There are functions in the backend that will double-quote their own output - at need (for example, <function>format_type_be()</function>). Do not put + as needed (for example, <function>format_type_be()</function>). Do not put additional quotes around the output of such functions. </para> @@ -880,16 +880,16 @@ BETTER: unrecognized node type: 42 practices. </para> <para> - Features from later revision of the C standard or compiler specific + Features from later revisions of the C standard or compiler specific features can be used, if a fallback is provided. </para> <para> - For example <literal>_StaticAssert()</literal> and + For example, <literal>_StaticAssert()</literal> and <literal>__builtin_constant_p</literal> are currently used, even though - they are from newer revisions of the C standard and a - <productname>GCC</productname> extension respectively. If not available - we respectively fall back to using a C99 compatible replacement that - performs the same checks, but emits rather cryptic messages and do not + they are from a newer revision of the C standard and a + <productname>GCC</productname> extension, respectively. If not available, in the first case, + we fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages; in the second case, we do not use <literal>__builtin_constant_p</literal>. </para> </simplesect> @@ -939,8 +939,8 @@ MemoryContextSwitchTo(MemoryContext context) To be suitable to run inside a signal handler code has to be written very carefully. The fundamental problem is that, unless blocked, a signal handler can interrupt code at any time. If code - inside the signal handler uses the same state as code outside - chaos may ensue. As an example consider what happens if a signal + inside the signal handler uses the same state as code outside, + chaos may ensue. As an example, consider what happens if a signal handler tries to acquire a lock that's already held in the interrupted code. </para> @@ -948,7 +948,7 @@ MemoryContextSwitchTo(MemoryContext context) Barring special arrangements code in signal handlers may only call async-signal safe functions (as defined in POSIX) and access variables of type <literal>volatile sig_atomic_t</literal>. A few - functions in <command>postgres</command> are also deemed signal safe, importantly + functions in <command>postgres</command> are also deemed signal safe; specifically, <function>SetLatch()</function>. </para> <para> @@ -969,9 +969,9 @@ handle_sighup(SIGNAL_ARGS) } </programlisting> <varname>errno</varname> is saved and restored because - <function>SetLatch()</function> might change it. If that were not done - interrupted code that's currently inspecting <varname>errno</varname> might see the wrong - value. + <function>SetLatch()</function> might change it. If that were not done, + code interrupted by a signal might see the wrong value of + <varname>errno</varname>. </para> </simplesect> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 3403269..5c17b10 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3364,11 +3364,11 @@ if (!ptr) </indexterm> <para> - By default, a function is just a <quote>black box</quote> that the - database system knows very little about the behavior of. However, - that means that queries using the function may be executed much less + By default, a function is a <quote>black box</quote> that the + database system knows very little about, which + means queries calling the function may be executed less efficiently than they could be. It is possible to supply additional - knowledge that helps the planner optimize function calls. + information that helps the planner optimize function calls. </para> <para> @@ -3381,7 +3381,7 @@ if (!ptr) The parallel safety property (<literal>PARALLEL UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or <literal>PARALLEL SAFE</literal>) must also be specified if you hope - to use the function in parallelized queries. + queries calling the function to use parallel query. It can also be useful to specify the function's estimated execution cost, and/or the number of rows a set-returning function is estimated to return. However, the declarative way of specifying those two @@ -3393,7 +3393,7 @@ if (!ptr) It is also possible to attach a <firstterm>planner support function</firstterm> to a SQL-callable function (called its <firstterm>target function</firstterm>), and thereby provide - knowledge about the target function that is too complex to be + information about the target function that is too complex to be represented declaratively. Planner support functions have to be written in C (although their target functions might not be), so this is an advanced feature that relatively few people will use. diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 617270f..370c7aa 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -222,13 +222,13 @@ output_completion_banner(char *analyze_script_file_name, /* Did we copy the free space files? */ if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) pg_log(PG_REPORT, - "Optimizer statistics are not transferred by pg_upgrade so,\n" - "once you start the new server, consider running:\n" + "Optimizer statistics are not transferred by pg_upgrade.\n" + "Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); else pg_log(PG_REPORT, "Optimizer statistics and free space information are not transferred\n" - "by pg_upgrade so, once you start the new server, consider running:\n" + "by pg_upgrade. Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); -- 2.7.4 --cWoXeonUoKmBZSoM Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0002-Add-comma-for-readability.patch" ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v5 01/12] review docs for pg12dev @ 2019-03-28 23:50 Justin Pryzby <pryzbyj@telsasoft.com> 0 siblings, 0 replies; 132+ messages in thread From: Justin Pryzby @ 2019-03-28 23:50 UTC (permalink / raw) --- doc/src/sgml/catalogs.sgml | 4 ++-- doc/src/sgml/config.sgml | 14 +++++++------ doc/src/sgml/ddl.sgml | 16 +++++++------- doc/src/sgml/ecpg.sgml | 16 +++++++------- doc/src/sgml/monitoring.sgml | 43 +++++++++++++++++++------------------- doc/src/sgml/perform.sgml | 8 +++---- doc/src/sgml/protocol.sgml | 6 +++--- doc/src/sgml/ref/create_index.sgml | 4 ++-- doc/src/sgml/ref/pg_rewind.sgml | 13 ++++++------ doc/src/sgml/ref/pgbench.sgml | 7 +++---- doc/src/sgml/ref/vacuum.sgml | 6 +++--- doc/src/sgml/runtime.sgml | 4 ++-- doc/src/sgml/sources.sgml | 18 ++++++++-------- doc/src/sgml/xfunc.sgml | 12 +++++------ src/bin/pg_upgrade/check.c | 6 +++--- 15 files changed, 87 insertions(+), 90 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 3428a7c..47482f2 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -3060,7 +3060,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l simplifies <command>ATTACH/DETACH PARTITION</command> operations: the partition dependencies need only be added or removed. Example: a child partitioned index is made partition-dependent - on both the partition table it is on and the parent partitioned + on both the table partition and the parent partitioned index, so that it goes away if either of those is dropped, but not otherwise. The dependency on the parent index is primary, so that if the user tries to drop the child partitioned index, @@ -3123,7 +3123,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l Note that it's quite possible for two objects to be linked by more than one <structname>pg_depend</structname> entry. For example, a child partitioned index would have both a partition-type dependency on its - associated partition table, and an auto dependency on each column of + associated table partition, and an auto dependency on each column of that table that it indexes. This sort of situation expresses the union of multiple dependency semantics. A dependent object can be dropped without <literal>CASCADE</literal> if any of its dependencies satisfies diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index aaab1c5..fa8b40a 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -3433,7 +3433,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows current when the base backup was taken. The value <literal>latest</literal> recovers to the latest timeline found in the archive, which is useful in - a standby server. <literal>latest</literal> is the default. + a standby server. The default is <literal>latest</literal>. </para> <para> @@ -4195,8 +4195,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class=" This parameter is intended for use with streaming replication deployments; however, if the parameter is specified it will be honored in all cases. - <varname>hot_standby_feedback</varname> will be delayed by use of this feature - which could lead to bloat on the master; use both together with care. + <varname>hot_standby_feedback</varname> will be delayed by use of this feature. + Combinining these settings could lead to bloat on the master, so should + be done only with care. <warning> <para> @@ -5305,9 +5306,10 @@ SELECT * FROM parent WHERE key = 2400; <listitem> <para> Prepared statements (either explicitly prepared or implicitly - generated, for example in PL/pgSQL) can be executed using custom or - generic plans. A custom plan is replanned for a new parameter value, - a generic plan is reused for repeated executions of the prepared + generated, for example in PL/pgSQL) can be executed using a custom or + generic plan. If executed with a custom plan, the prepared statement + is replanned for its specific parameter values; if executed with a + generic plan, the same plan is reused for repeated executions of the prepared statement. The choice between them is normally made automatically. This setting overrides the default behavior and forces either a custom or a generic plan. This can be used to work around performance diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index ed2d9c6..cf390a2 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -3868,12 +3868,12 @@ CREATE INDEX ON measurement (logdate); <para> Normally the set of partitions established when initially defining the - table are not intended to remain static. It is common to want to - remove old partitions of data and periodically add new partitions for + table are not intended to remain static. It is common to + remove partitions of old data and add partitions for new data. One of the most important advantages of partitioning is - precisely that it allows this otherwise painful task to be executed + allowing this otherwise painful task to be executed nearly instantaneously by manipulating the partition structure, rather - than physically moving large amounts of data around. + than physically moving around large amounts of data. </para> <para> @@ -3951,10 +3951,10 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 </para> <para> - As explained above, it is possible to create indexes on partitioned tables - and they are applied automatically to the entire hierarchy. This is very - convenient, as not only the existing partitions will become indexed, but - also any partitions that are created in the future will. One limitation is + As explained above, it is possible to create indexes on partitioned tables; + such indexes are propagated automatically to the entire hierarchy, and + any partitions created in the future will be indexed, in addition to the + existing partitions. One limitation is that it's not possible to use the <literal>CONCURRENTLY</literal> qualifier when creating such a partitioned index. To overcome long lock times, it is possible to use <command>CREATE INDEX ON ONLY</command> diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index 6641eee..d2dd96c 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -979,7 +979,7 @@ EXEC SQL END DECLARE SECTION; <para> The other way is using the <type>VARCHAR</type> type, which is a - special type provided by ECPG. The definition on an array of + special type provided by ECPG. The definition of an array of type <type>VARCHAR</type> is converted into a named <type>struct</type> for every variable. A declaration like: <programlisting> @@ -989,7 +989,7 @@ VARCHAR var[180]; <programlisting> struct varchar_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts the string + The member <structfield>arr</structfield> stores the string including a terminating zero byte. Thus, to store a string in a <type>VARCHAR</type> host variable, the host variable has to be declared with the length including the zero byte terminator. The @@ -1209,8 +1209,8 @@ EXEC SQL END DECLARE SECTION; <title id="ecpg-type-bytea">bytea</title> <para> - The handling of the <type>bytea</type> type is also similar to - the <type>VARCHAR</type>. The definition on an array of type + The handling of the <type>bytea</type> type is similar to + the <type>VARCHAR</type>. The definition of an array of type <type>bytea</type> is converted into a named struct for every variable. A declaration like: <programlisting> @@ -1220,9 +1220,8 @@ bytea var[180]; <programlisting> struct bytea_var { int len; char arr[180]; } var; </programlisting> - The member <structfield>arr</structfield> hosts binary format - data. It also can handle even <literal>'\0'</literal> as part of - data unlike <type>VARCHAR</type>. + The member <structfield>arr</structfield> stores binary format + data, which can include zero bytes, unlike <type>VARCHAR</type>. The data is converted from/to hex format and sent/received by ecpglib. </para> @@ -7571,8 +7570,7 @@ PREPARE <replaceable class="parameter">name</replaceable> FROM <replaceable clas <listitem> <para> A literal C string or a host variable containing a preparable - statement, one of the SELECT, INSERT, UPDATE, or - DELETE. + statement (SELECT, INSERT, UPDATE, or DELETE). </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index bf72d0c..7cec551 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -271,13 +271,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <para> Some of the information in the dynamic statistics views shown in <xref linkend="monitoring-stats-dynamic-views-table"/> is security restricted. - Ordinary users can only see all the information about their own sessions - (sessions belonging to a role that they are a member of). In rows about + Ordinary users can only see all information about their own sessions + (sessions belonging to a role of which they are a member). In rows for other sessions, many columns will be null. Note, however, that the existence of a session and its general properties such as its sessions user and database are visible to all users. Superusers and members of the built-in role <literal>pg_read_all_stats</literal> (see also <xref - linkend="default-roles"/>) can see all the information about all sessions. + linkend="default-roles"/>) can see all information about all sessions. </para> <table id="monitoring-stats-dynamic-views-table"> @@ -667,7 +667,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <entry><type>timestamp with time zone</type></entry> <entry>Time when this process' current transaction was started, or null if no transaction is active. If the current - query is the first of its transaction, this column is equal to the + query is the first of its transaction, this is equal to the <structfield>query_start</structfield> column. </entry> </row> @@ -3603,16 +3603,16 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <entry><structfield>partitions_total</structfield></entry> <entry><type>bigint</type></entry> <entry> - When creating an index on a partitioned table, this column is set to - the total number of partitions on which the index is to be created. + When creating an index on a partitioned table, this is + the total number of partitions to be processed. </entry> </row> <row> <entry><structfield>partitions_done</structfield></entry> <entry><type>bigint</type></entry> <entry> - When creating an index on a partitioned table, this column is set to - the number of partitions on which the index has been completed. + When creating an index on a partitioned table, this is + the number of partitions for which the process is complete. </entry> </row> </tbody> @@ -3650,11 +3650,10 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <row> <entry><literal>building index</literal></entry> <entry> - The index is being built by the access method-specific code. In this phase, - access methods that support progress reporting fill in their own progress data, - and the subphase is indicated in this column. Typically, + The index is being built by code specific to the access method, and if + it supports progress reporting, this indicates the method's subphase. <structname>blocks_total</structname> and <structname>blocks_done</structname> - will contain progress data, as well as potentially + will contain progress data, as may <structname>tuples_total</structname> and <structname>tuples_done</structname>. </entry> </row> @@ -3739,15 +3738,15 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>VACUUM Progress Reporting</title> <para> - Whenever <command>VACUUM</command> is running, the - <structname>pg_stat_progress_vacuum</structname> view will contain - one row for each backend (including autovacuum worker processes) that is - currently vacuuming. The tables below describe the information + The <structname>pg_stat_progress_vacuum</structname> view will contain one + row for each backend that is running <command>VACUUM</command>, including + autovacuum worker processes. + The tables below describe the information that will be reported and provide information about how to interpret it. Progress for <command>VACUUM FULL</command> commands is reported via - <structname>pg_stat_progress_cluster</structname> - because both <command>VACUUM FULL</command> and <command>CLUSTER</command> - rewrite the table, while regular <command>VACUUM</command> only modifies it + <structname>pg_stat_progress_cluster</structname>, + because <command>VACUUM FULL</command> rewrites the table, like <command>CLUSTER</command>, + while regular <command>VACUUM</command> only modifies it in place. See <xref linkend='cluster-progress-reporting'/>. </para> @@ -3931,9 +3930,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <title>CLUSTER Progress Reporting</title> <para> - Whenever <command>CLUSTER</command> or <command>VACUUM FULL</command> is - running, the <structname>pg_stat_progress_cluster</structname> view will - contain a row for each backend that is currently running either command. + The <structname>pg_stat_progress_cluster</structname> view will contain a + row for each backend that is running either + <command>CLUSTER</command> or <command>VACUUM FULL</command>. The tables below describe the information that will be reported and provide information about how to interpret it. </para> diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml index 8e16583..0e34652 100644 --- a/doc/src/sgml/perform.sgml +++ b/doc/src/sgml/perform.sgml @@ -899,10 +899,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 Generally, the <command>EXPLAIN</command> output will display details for every plan node which was generated by the query planner. However, there are cases where the executor is able to determine that certain nodes are - not required; currently, the only node types to support this are the - <literal>Append</literal> and <literal>MergeAppend</literal> nodes. These - node types have the ability to discard subnodes which they are able to - determine won't contain any records required by the query. It is possible + not required; currently, the only node types to support this are + <literal>Append</literal> and <literal>MergeAppend</literal>, which + are able to discard subnodes when it's deduced that + they will not contain any records required by the query. It is possible to determine that nodes have been removed in this way by the presence of a "Subplans Removed" property in the <command>EXPLAIN</command> output. </para> diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index b20f169..70f7286 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -1515,7 +1515,7 @@ SELECT 1/0; the server will only accept encrypted packets from the client which are less than 16kB; <function>gss_wrap_size_limit()</function> should be used by the client to determine the size of the unencrypted message which will fit - within this limit and larger messages should be broken up into multiple + within this limit; larger messages should be broken up into multiple <function>gss_wrap()</function> calls. Typical segments are 8kB of unencrypted data, resulting in encrypted packets of slightly larger than 8kB but well within the 16kB maximum. The server can be expected to not send @@ -1531,8 +1531,8 @@ SELECT 1/0; support to <productname>PostgreSQL</productname>. In this case the connection must be closed, but the frontend might choose to open a fresh connection and proceed without requesting <acronym>GSSAPI</acronym> - encryption. Given the length limits specified above, the ErrorMessage can - not be confused with a proper response from the server with an appropriate + encryption. Given the length limits specified above, the ErrorMessage + cannot be confused with a proper response from the server with an appropriate length. </para> diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 629a31e..713e2c3 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -181,8 +181,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= </para> <para> - Currently, the B-tree and the GiST index access methods support this - feature. In B-tree and the GiST indexes, the values of columns listed + Currently, only the B-tree and GiST index access methods support this + feature. In B-tree and GiST indexes, the values of columns listed in the <literal>INCLUDE</literal> clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index 4d91eeb..f39fe53 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -106,15 +106,14 @@ PostgreSQL documentation </para> <para> - <application>pg_rewind</application> will fail immediately if it finds - files it cannot write directly to. This can happen for example when - the source and the target server use the same file mapping for read-only - SSL keys and certificates. If such files are present on the target server + <application>pg_rewind</application> will fail immediately if it experiences + a write error. This can happen for example when + the source and target server use the same file mapping for read-only + SSL keys and certificates. If such files are present on the target server, it is recommended to remove them before running - <application>pg_rewind</application>. After doing the rewind, some of + <application>pg_rewind</application>. After performing the rewind, some of those files may have been copied from the source, in which case it may - be necessary to remove the data copied and restore back the set of links - used before the rewind. + be necessary to remove them and restore the files removed beforehand. </para> </warning> </refsect1> diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index e3b73a4..cc2e533 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -474,10 +474,9 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d </listitem> </itemizedlist> - Because in "prepared" mode <application>pgbench</application> reuses - the parse analysis result for the second and subsequent query - iteration, <application>pgbench</application> runs faster in the - prepared mode than in other modes. + <application>pgbench</application> runs faster in prepared mode because + parse analysis and planning are done only once rather than during each + query. </para> <para> The default is simple query protocol. (See <xref linkend="protocol"/> diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index f9b0fb8..ec2503d 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -215,9 +215,9 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet the operating system. This is normally the desired behavior and is the default unless the <literal>vacuum_truncate</literal> option has been set to false for the table to be vacuumed. - Setting this option to false may be useful to avoid - <literal>ACCESS EXCLUSIVE</literal> lock on the table that - the truncation requires. This option is ignored if the + Setting this option to false may be useful to avoid an + <literal>ACCESS EXCLUSIVE</literal> lock on the table as needed for + truncation. This option is ignored if the <literal>FULL</literal> option is used. </para> </listitem> diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 365ec75..cefff77 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -2632,8 +2632,8 @@ openssl x509 -req -in server.csr -text -days 365 \ using <acronym>GSSAPI</acronym> to encrypt client/server communications for increased security. Support requires that a <acronym>GSSAPI</acronym> implementation (such as MIT krb5) is installed on both client and server - systems, and that support in <productname>PostgreSQL</productname> is - enabled at build time (see <xref linkend="installation"/>). + systems, and that <productname>PostgreSQL</productname> was built with + <acronym>GSSAPI</acronym> support (see <xref linkend="installation"/>). </para> <sect2 id="gssapi-setup"> diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index a339ebb..e869a31 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -103,7 +103,7 @@ less -x4 message text. In addition there are optional elements, the most common of which is an error identifier code that follows the SQL spec's SQLSTATE conventions. - <function>ereport</function> itself is just a shell function, that exists + <function>ereport</function> itself is just a shell function that exists mainly for the syntactic convenience of making message generation look like a function call in the C source code. The only parameter accepted directly by <function>ereport</function> is the severity level. @@ -886,10 +886,10 @@ BETTER: unrecognized node type: 42 <para> For example <literal>_StaticAssert()</literal> and <literal>__builtin_constant_p</literal> are currently used, even though - they are from newer revisions of the C standard and a - <productname>GCC</productname> extension respectively. If not available - we respectively fall back to using a C99 compatible replacement that - performs the same checks, but emits rather cryptic messages and do not + they are from a newer revision of the C standard and a + <productname>GCC</productname> extension, respectively. If not available, in the first case, + we fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages; in the second case, we do not use <literal>__builtin_constant_p</literal>. </para> </simplesect> @@ -948,7 +948,7 @@ MemoryContextSwitchTo(MemoryContext context) Barring special arrangements code in signal handlers may only call async-signal safe functions (as defined in POSIX) and access variables of type <literal>volatile sig_atomic_t</literal>. A few - functions in <command>postgres</command> are also deemed signal safe, importantly + functions in <command>postgres</command> are also deemed signal safe; specifically, <function>SetLatch()</function>. </para> <para> @@ -969,9 +969,9 @@ handle_sighup(SIGNAL_ARGS) } </programlisting> <varname>errno</varname> is saved and restored because - <function>SetLatch()</function> might change it. If that were not done - interrupted code that's currently inspecting <varname>errno</varname> might see the wrong - value. + <function>SetLatch()</function> might change it. If that were not done, + code interrupted by a signal might see the wrong value of + <varname>errno</varname>. </para> </simplesect> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 34a1938..d14457b 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3364,11 +3364,11 @@ if (!ptr) </indexterm> <para> - By default, a function is just a <quote>black box</quote> that the - database system knows very little about the behavior of. However, - that means that queries using the function may be executed much less + By default, a function is a <quote>black box</quote> that the + database system knows very little about, which + means queries calling the function may be executed less efficiently than they could be. It is possible to supply additional - knowledge that helps the planner optimize function calls. + information that helps the planner optimize function calls. </para> <para> @@ -3381,7 +3381,7 @@ if (!ptr) The parallel safety property (<literal>PARALLEL UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or <literal>PARALLEL SAFE</literal>) must also be specified if you hope - to use the function in parallelized queries. + queries calling the function to be run using the parallel infrastructure. It can also be useful to specify the function's estimated execution cost, and/or the number of rows a set-returning function is estimated to return. However, the declarative way of specifying those two @@ -3393,7 +3393,7 @@ if (!ptr) It is also possible to attach a <firstterm>planner support function</firstterm> to a SQL-callable function (called its <firstterm>target function</firstterm>), and thereby provide - knowledge about the target function that is too complex to be + information about the target function that is too complex to be represented declaratively. Planner support functions have to be written in C (although their target functions might not be), so this is an advanced feature that relatively few people will use. diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 617270f..370c7aa 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -222,13 +222,13 @@ output_completion_banner(char *analyze_script_file_name, /* Did we copy the free space files? */ if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) pg_log(PG_REPORT, - "Optimizer statistics are not transferred by pg_upgrade so,\n" - "once you start the new server, consider running:\n" + "Optimizer statistics are not transferred by pg_upgrade.\n" + "Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); else pg_log(PG_REPORT, "Optimizer statistics and free space information are not transferred\n" - "by pg_upgrade so, once you start the new server, consider running:\n" + "by pg_upgrade. Once you start the new server, consider running:\n" " %s\n\n", analyze_script_file_name); -- 2.7.4 --FkmkrVfFsRoUs1wW Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v5-0002-Say-it-more-naturally.patch" ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH] use C99 named designators @ 2023-08-23 10:19 Alvaro Herrera <alvherre@alvh.no-ip.org> 0 siblings, 0 replies; 132+ messages in thread From: Alvaro Herrera @ 2023-08-23 10:19 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 29 +++++++++++++++-------------- src/backend/postmaster/bgworker.c | 18 ++++++++++++------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index f30a56ecf55..75a77052cd4 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -127,29 +127,30 @@ static const struct LOCKMODE hwlock; int lockstatus; int updstatus; -} +} tupleLockExtraInfo[] = - tupleLockExtraInfo[MaxLockTupleMode + 1] = { { /* LockTupleKeyShare */ - AccessShareLock, - MultiXactStatusForKeyShare, - -1 /* KeyShare does not allow updating tuples */ + .hwlock = AccessShareLock, + .lockstatus = MultiXactStatusForKeyShare, + /* KeyShare does not allow updating tuples */ + .updstatus = -1 }, { /* LockTupleShare */ - RowShareLock, - MultiXactStatusForShare, - -1 /* Share does not allow updating tuples */ + .hwlock = RowShareLock, + .lockstatus = MultiXactStatusForShare, + /* Share does not allow updating tuples */ + .updstatus = -1 }, { /* LockTupleNoKeyExclusive */ - ExclusiveLock, - MultiXactStatusForNoKeyUpdate, - MultiXactStatusNoKeyUpdate + .hwlock = ExclusiveLock, + .lockstatus = MultiXactStatusForNoKeyUpdate, + .updstatus = MultiXactStatusNoKeyUpdate }, { /* LockTupleExclusive */ - AccessExclusiveLock, - MultiXactStatusForUpdate, - MultiXactStatusUpdate + .hwlock = AccessExclusiveLock, + .lockstatus = MultiXactStatusForUpdate, + .updstatus = MultiXactStatusUpdate } }; diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 65deabe91a7..51874481751 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -120,22 +120,28 @@ static const struct { { - "ParallelWorkerMain", ParallelWorkerMain + .fn_name = "ParallelWorkerMain", + .fn_addr = ParallelWorkerMain }, { - "ApplyLauncherMain", ApplyLauncherMain + .fn_name = "ApplyLauncherMain", + .fn_addr = ApplyLauncherMain }, { - "ApplyWorkerMain", ApplyWorkerMain + .fn_name = "ApplyWorkerMain", + .fn_addr = ApplyWorkerMain }, { - "ParallelApplyWorkerMain", ParallelApplyWorkerMain + .fn_name = "ParallelApplyWorkerMain", + .fn_addr = ParallelApplyWorkerMain }, { - "TableSyncWorkerMain", TableSyncWorkerMain + .fn_name = "TableSyncWorkerMain", + .fn_addr = TableSyncWorkerMain }, { - "SequenceSyncWorkerMain", SequenceSyncWorkerMain + .fn_name = "SequenceSyncWorkerMain", + .fn_addr = SequenceSyncWorkerMain } }; -- 2.47.3 --hedw4mraldmc2ejv-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v17] Avoid orphaned objects dependencies @ 2024-03-29 15:43 Bertrand Drouvot <bertranddrouvot.pg@gmail.com> 0 siblings, 0 replies; 132+ messages in thread From: Bertrand Drouvot @ 2024-03-29 15:43 UTC (permalink / raw) It's currently possible to create orphaned objects dependencies, for example: Scenario 1: session 1: begin; drop schema schem; session 2: create a function in the schema schem session 1: commit; With the above, the function created in session 2 would be linked to a non existing schema. Scenario 2: session 1: begin; create a function in the schema schem session 2: drop schema schem; session 1: commit; With the above, the function created in session 1 would be linked to a non existing schema. To avoid those scenarios, a new lock (that conflicts with a lock taken by DROP) has been put in place before the dependencies are being recorded. With this in place, the drop schema in scenario 2 would be locked. Also, after the new lock attempt, the patch checks that the object still exists: with this in place session 2 in scenario 1 would be locked and would report an error once session 1 committs (that would not be the case should session 1 abort the transaction). If the object is dropped before the new lock attempt is triggered then the patch would also report an error (but with less details). The patch takes into account any type of objects except the ones that are pinned (they are not droppable because the system requires it). A special case is done for objects that belong to the RelationRelationId class. For those, we should be in one of the two following cases that would already prevent the relation to be dropped: 1. The relation is already locked (could be an existing relation or a relation that we are creating). 2. The relation is protected indirectly (i.e an index protected by a lock on its table, a table protected by a lock on a function that depends the table...) To avoid any risks for the RelationRelationId class case, we acquire a lock if there is none. That may add unnecessary lock for 2. but that's worth it. The patch adds a few tests for some dependency cases (that would currently produce orphaned objects): - schema and function (as the above scenarios) - alter a dependency (function and schema) - function and arg type - function and return type - function and function - domain and domain - table and type - server and foreign data wrapper --- src/backend/catalog/aclchk.c | 1 + src/backend/catalog/dependency.c | 212 ++++++++++++++++++ src/backend/catalog/heap.c | 7 + src/backend/catalog/index.c | 26 +++ src/backend/catalog/objectaddress.c | 57 +++++ src/backend/catalog/pg_aggregate.c | 9 + src/backend/catalog/pg_attrdef.c | 1 + src/backend/catalog/pg_cast.c | 5 + src/backend/catalog/pg_collation.c | 1 + src/backend/catalog/pg_constraint.c | 26 +++ src/backend/catalog/pg_conversion.c | 2 + src/backend/catalog/pg_depend.c | 39 +++- src/backend/catalog/pg_operator.c | 19 ++ src/backend/catalog/pg_proc.c | 17 +- src/backend/catalog/pg_publication.c | 11 + src/backend/catalog/pg_range.c | 6 + src/backend/catalog/pg_type.c | 39 ++++ src/backend/catalog/toasting.c | 1 + src/backend/commands/alter.c | 4 + src/backend/commands/amcmds.c | 1 + src/backend/commands/cluster.c | 7 + src/backend/commands/event_trigger.c | 1 + src/backend/commands/extension.c | 5 + src/backend/commands/foreigncmds.c | 7 + src/backend/commands/functioncmds.c | 6 + src/backend/commands/indexcmds.c | 2 + src/backend/commands/opclasscmds.c | 18 ++ src/backend/commands/operatorcmds.c | 30 +++ src/backend/commands/policy.c | 2 + src/backend/commands/proclang.c | 3 + src/backend/commands/sequence.c | 2 + src/backend/commands/statscmds.c | 10 + src/backend/commands/tablecmds.c | 24 +- src/backend/commands/trigger.c | 29 ++- src/backend/commands/tsearchcmds.c | 73 +++++- src/backend/commands/typecmds.c | 84 +++++++ src/backend/rewrite/rewriteDefine.c | 1 + src/backend/utils/errcodes.txt | 1 + src/include/catalog/dependency.h | 3 + src/include/catalog/objectaddress.h | 1 + .../expected/test_dependencies_locks.out | 129 +++++++++++ src/test/isolation/isolation_schedule | 1 + .../specs/test_dependencies_locks.spec | 89 ++++++++ .../test_oat_hooks/expected/alter_table.out | 4 +- .../expected/test_oat_hooks.out | 2 + src/test/regress/expected/alter_table.out | 11 +- 46 files changed, 1009 insertions(+), 20 deletions(-) 40.0% src/backend/catalog/ 29.8% src/backend/commands/ 16.8% src/test/isolation/expected/ 10.5% src/test/isolation/specs/ diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 95eb0b1227..176bd46261 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -1414,6 +1414,7 @@ SetDefaultACL(InternalDefaultACL *iacls) referenced.objectId = iacls->nspid; referenced.objectSubId = 0; + LockNotPinnedObject(NamespaceRelationId, iacls->nspid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); } } diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 0489cbabcb..a3770d7206 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1519,6 +1519,81 @@ AcquireDeletionLock(const ObjectAddress *object, int flags) } } +/* + * LockNotPinnedObjectById + * + * Lock the object that we are about to record a dependency on. + * After it's locked, verify that it hasn't been dropped while we + * weren't looking. If the object has been dropped, this function + * does not return! + */ +void +LockNotPinnedObjectById(const ObjectAddress *object) +{ + char *object_description = NULL; + + if (isObjectPinned(object)) + return; + + object_description = getObjectDescription(object, true); + + if (object->classId == RelationRelationId) + { + Assert(!IsSharedRelation(object->objectId)); + + /* + * We must be in one of the two following cases that would already + * prevent the relation to be dropped: 1. The relation is already + * locked (could be an existing relation or a relation that we are + * creating). 2. The relation is protected indirectly (i.e an index + * protected by a lock on its table, a table protected by a lock on a + * function that depends of the table...). To avoid any risks, acquire + * a lock if there is none. That may add unnecessary lock for 2. but + * that's worth it. + */ + if (!CheckRelationOidLockedByMe(object->objectId, AccessShareLock, true)) + LockRelationOid(object->objectId, AccessShareLock); + } + else + { + /* assume we should lock the whole object not a sub-object */ + LockDatabaseObject(object->classId, object->objectId, 0, AccessShareLock); + } + + /* check if object still exists */ + if (!ObjectByIdExist(object)) + { + if (object_description) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_DOES_NOT_EXIST), + errmsg("%s does not exist", object_description))); + else + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_DOES_NOT_EXIST), + errmsg("a dependent object does not exist"))); + } + + if (object_description) + pfree(object_description); + + return; +} + +/* + * LockNotPinnedObject + * + * Lock the object that we are about to record a dependency on. + */ +void +LockNotPinnedObject(Oid classid, Oid objid) +{ + ObjectAddress object; + + ObjectAddressSet(object, classid, objid); + + LockNotPinnedObjectById(&object); +} + /* * ReleaseDeletionLock - release an object deletion lock * @@ -1730,6 +1805,7 @@ find_expr_references_walker(Node *node, if (rte->rtekind == RTE_RELATION) { /* If it's a plain relation, reference this column */ + LockNotPinnedObject(RelationRelationId, rte->relid); add_object_address(RelationRelationId, rte->relid, var->varattno, context->addrs); } @@ -1756,6 +1832,7 @@ find_expr_references_walker(Node *node, Oid objoid; /* A constant must depend on the constant's datatype */ + LockNotPinnedObject(TypeRelationId, con->consttype); add_object_address(TypeRelationId, con->consttype, 0, context->addrs); @@ -1767,8 +1844,11 @@ find_expr_references_walker(Node *node, */ if (OidIsValid(con->constcollid) && con->constcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, con->constcollid); add_object_address(CollationRelationId, con->constcollid, 0, context->addrs); + } /* * If it's a regclass or similar literal referring to an existing @@ -1785,59 +1865,83 @@ find_expr_references_walker(Node *node, objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(ProcedureRelationId, objoid); add_object_address(ProcedureRelationId, objoid, 0, context->addrs); + } break; case REGOPEROID: case REGOPERATOROID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(OPEROID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(OperatorRelationId, objoid); add_object_address(OperatorRelationId, objoid, 0, context->addrs); + } break; case REGCLASSOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(RELOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(RelationRelationId, objoid); add_object_address(RelationRelationId, objoid, 0, context->addrs); + } break; case REGTYPEOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(TypeRelationId, objoid); add_object_address(TypeRelationId, objoid, 0, context->addrs); + } break; case REGCOLLATIONOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(COLLOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(CollationRelationId, objoid); add_object_address(CollationRelationId, objoid, 0, context->addrs); + } break; case REGCONFIGOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(TSConfigRelationId, objoid); add_object_address(TSConfigRelationId, objoid, 0, context->addrs); + } break; case REGDICTIONARYOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(TSDictionaryRelationId, objoid); add_object_address(TSDictionaryRelationId, objoid, 0, context->addrs); + } break; case REGNAMESPACEOID: objoid = DatumGetObjectId(con->constvalue); if (SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(objoid))) + { + LockNotPinnedObject(NamespaceRelationId, objoid); add_object_address(NamespaceRelationId, objoid, 0, context->addrs); + } break; /* @@ -1859,18 +1963,23 @@ find_expr_references_walker(Node *node, Param *param = (Param *) node; /* A parameter must depend on the parameter's datatype */ + LockNotPinnedObject(TypeRelationId, param->paramtype); add_object_address(TypeRelationId, param->paramtype, 0, context->addrs); /* and its collation, just as for Consts */ if (OidIsValid(param->paramcollid) && param->paramcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, param->paramcollid); add_object_address(CollationRelationId, param->paramcollid, 0, context->addrs); + } } else if (IsA(node, FuncExpr)) { FuncExpr *funcexpr = (FuncExpr *) node; + LockNotPinnedObject(ProcedureRelationId, funcexpr->funcid); add_object_address(ProcedureRelationId, funcexpr->funcid, 0, context->addrs); /* fall through to examine arguments */ @@ -1879,6 +1988,7 @@ find_expr_references_walker(Node *node, { OpExpr *opexpr = (OpExpr *) node; + LockNotPinnedObject(OperatorRelationId, opexpr->opno); add_object_address(OperatorRelationId, opexpr->opno, 0, context->addrs); /* fall through to examine arguments */ @@ -1887,6 +1997,7 @@ find_expr_references_walker(Node *node, { DistinctExpr *distinctexpr = (DistinctExpr *) node; + LockNotPinnedObject(OperatorRelationId, distinctexpr->opno); add_object_address(OperatorRelationId, distinctexpr->opno, 0, context->addrs); /* fall through to examine arguments */ @@ -1895,6 +2006,7 @@ find_expr_references_walker(Node *node, { NullIfExpr *nullifexpr = (NullIfExpr *) node; + LockNotPinnedObject(OperatorRelationId, nullifexpr->opno); add_object_address(OperatorRelationId, nullifexpr->opno, 0, context->addrs); /* fall through to examine arguments */ @@ -1903,6 +2015,7 @@ find_expr_references_walker(Node *node, { ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node; + LockNotPinnedObject(OperatorRelationId, opexpr->opno); add_object_address(OperatorRelationId, opexpr->opno, 0, context->addrs); /* fall through to examine arguments */ @@ -1911,6 +2024,7 @@ find_expr_references_walker(Node *node, { Aggref *aggref = (Aggref *) node; + LockNotPinnedObject(ProcedureRelationId, aggref->aggfnoid); add_object_address(ProcedureRelationId, aggref->aggfnoid, 0, context->addrs); /* fall through to examine arguments */ @@ -1919,6 +2033,7 @@ find_expr_references_walker(Node *node, { WindowFunc *wfunc = (WindowFunc *) node; + LockNotPinnedObject(ProcedureRelationId, wfunc->winfnoid); add_object_address(ProcedureRelationId, wfunc->winfnoid, 0, context->addrs); /* fall through to examine arguments */ @@ -1935,8 +2050,11 @@ find_expr_references_walker(Node *node, */ if (sbsref->refrestype != sbsref->refcontainertype && sbsref->refrestype != sbsref->refelemtype) + { + LockNotPinnedObject(TypeRelationId, sbsref->refrestype); add_object_address(TypeRelationId, sbsref->refrestype, 0, context->addrs); + } /* fall through to examine arguments */ } else if (IsA(node, SubPlan)) @@ -1960,16 +2078,25 @@ find_expr_references_walker(Node *node, * anywhere else in the expression. */ if (OidIsValid(reltype)) + { + LockNotPinnedObject(RelationRelationId, reltype); add_object_address(RelationRelationId, reltype, fselect->fieldnum, context->addrs); + } else + { + LockNotPinnedObject(TypeRelationId, fselect->resulttype); add_object_address(TypeRelationId, fselect->resulttype, 0, context->addrs); + } /* the collation might not be referenced anywhere else, either */ if (OidIsValid(fselect->resultcollid) && fselect->resultcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, fselect->resultcollid); add_object_address(CollationRelationId, fselect->resultcollid, 0, context->addrs); + } } else if (IsA(node, FieldStore)) { @@ -1980,53 +2107,76 @@ find_expr_references_walker(Node *node, if (OidIsValid(reltype)) { ListCell *l; + bool locked = false; foreach(l, fstore->fieldnums) + { + if (!locked) + { + LockNotPinnedObject(RelationRelationId, reltype); + locked = true; + } add_object_address(RelationRelationId, reltype, lfirst_int(l), context->addrs); + } } else + { + LockNotPinnedObject(TypeRelationId, fstore->resulttype); add_object_address(TypeRelationId, fstore->resulttype, 0, context->addrs); + } } else if (IsA(node, RelabelType)) { RelabelType *relab = (RelabelType *) node; /* since there is no function dependency, need to depend on type */ + LockNotPinnedObject(TypeRelationId, relab->resulttype); add_object_address(TypeRelationId, relab->resulttype, 0, context->addrs); /* the collation might not be referenced anywhere else, either */ if (OidIsValid(relab->resultcollid) && relab->resultcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, relab->resultcollid); add_object_address(CollationRelationId, relab->resultcollid, 0, context->addrs); + } } else if (IsA(node, CoerceViaIO)) { CoerceViaIO *iocoerce = (CoerceViaIO *) node; /* since there is no exposed function, need to depend on type */ + LockNotPinnedObject(TypeRelationId, iocoerce->resulttype); add_object_address(TypeRelationId, iocoerce->resulttype, 0, context->addrs); /* the collation might not be referenced anywhere else, either */ if (OidIsValid(iocoerce->resultcollid) && iocoerce->resultcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, iocoerce->resultcollid); add_object_address(CollationRelationId, iocoerce->resultcollid, 0, context->addrs); + } } else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; /* as above, depend on type */ + LockNotPinnedObject(TypeRelationId, acoerce->resulttype); add_object_address(TypeRelationId, acoerce->resulttype, 0, context->addrs); /* the collation might not be referenced anywhere else, either */ if (OidIsValid(acoerce->resultcollid) && acoerce->resultcollid != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, acoerce->resultcollid); add_object_address(CollationRelationId, acoerce->resultcollid, 0, context->addrs); + } /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) @@ -2034,6 +2184,7 @@ find_expr_references_walker(Node *node, ConvertRowtypeExpr *cvt = (ConvertRowtypeExpr *) node; /* since there is no function dependency, need to depend on type */ + LockNotPinnedObject(TypeRelationId, cvt->resulttype); add_object_address(TypeRelationId, cvt->resulttype, 0, context->addrs); } @@ -2041,6 +2192,7 @@ find_expr_references_walker(Node *node, { CollateExpr *coll = (CollateExpr *) node; + LockNotPinnedObject(CollationRelationId, coll->collOid); add_object_address(CollationRelationId, coll->collOid, 0, context->addrs); } @@ -2048,6 +2200,7 @@ find_expr_references_walker(Node *node, { RowExpr *rowexpr = (RowExpr *) node; + LockNotPinnedObject(TypeRelationId, rowexpr->row_typeid); add_object_address(TypeRelationId, rowexpr->row_typeid, 0, context->addrs); } @@ -2058,11 +2211,13 @@ find_expr_references_walker(Node *node, foreach(l, rcexpr->opnos) { + LockNotPinnedObject(OperatorRelationId, lfirst_oid(l)); add_object_address(OperatorRelationId, lfirst_oid(l), 0, context->addrs); } foreach(l, rcexpr->opfamilies) { + LockNotPinnedObject(OperatorFamilyRelationId, lfirst_oid(l)); add_object_address(OperatorFamilyRelationId, lfirst_oid(l), 0, context->addrs); } @@ -2072,6 +2227,7 @@ find_expr_references_walker(Node *node, { CoerceToDomain *cd = (CoerceToDomain *) node; + LockNotPinnedObject(TypeRelationId, cd->resulttype); add_object_address(TypeRelationId, cd->resulttype, 0, context->addrs); } @@ -2079,6 +2235,7 @@ find_expr_references_walker(Node *node, { NextValueExpr *nve = (NextValueExpr *) node; + LockNotPinnedObject(RelationRelationId, nve->seqid); add_object_address(RelationRelationId, nve->seqid, 0, context->addrs); } @@ -2087,19 +2244,26 @@ find_expr_references_walker(Node *node, OnConflictExpr *onconflict = (OnConflictExpr *) node; if (OidIsValid(onconflict->constraint)) + { + LockNotPinnedObject(ConstraintRelationId, onconflict->constraint); add_object_address(ConstraintRelationId, onconflict->constraint, 0, context->addrs); + } /* fall through to examine arguments */ } else if (IsA(node, SortGroupClause)) { SortGroupClause *sgc = (SortGroupClause *) node; + LockNotPinnedObject(OperatorRelationId, sgc->eqop); add_object_address(OperatorRelationId, sgc->eqop, 0, context->addrs); if (OidIsValid(sgc->sortop)) + { + LockNotPinnedObject(OperatorRelationId, sgc->sortop); add_object_address(OperatorRelationId, sgc->sortop, 0, context->addrs); + } return false; } else if (IsA(node, WindowClause)) @@ -2107,15 +2271,24 @@ find_expr_references_walker(Node *node, WindowClause *wc = (WindowClause *) node; if (OidIsValid(wc->startInRangeFunc)) + { + LockNotPinnedObject(ProcedureRelationId, wc->startInRangeFunc); add_object_address(ProcedureRelationId, wc->startInRangeFunc, 0, context->addrs); + } if (OidIsValid(wc->endInRangeFunc)) + { + LockNotPinnedObject(ProcedureRelationId, wc->endInRangeFunc); add_object_address(ProcedureRelationId, wc->endInRangeFunc, 0, context->addrs); + } if (OidIsValid(wc->inRangeColl) && wc->inRangeColl != DEFAULT_COLLATION_OID) + { + LockNotPinnedObject(CollationRelationId, wc->inRangeColl); add_object_address(CollationRelationId, wc->inRangeColl, 0, context->addrs); + } /* fall through to examine substructure */ } else if (IsA(node, CTECycleClause)) @@ -2123,14 +2296,23 @@ find_expr_references_walker(Node *node, CTECycleClause *cc = (CTECycleClause *) node; if (OidIsValid(cc->cycle_mark_type)) + { + LockNotPinnedObject(TypeRelationId, cc->cycle_mark_type); add_object_address(TypeRelationId, cc->cycle_mark_type, 0, context->addrs); + } if (OidIsValid(cc->cycle_mark_collation)) + { + LockNotPinnedObject(CollationRelationId, cc->cycle_mark_collation); add_object_address(CollationRelationId, cc->cycle_mark_collation, 0, context->addrs); + } if (OidIsValid(cc->cycle_mark_neop)) + { + LockNotPinnedObject(OperatorRelationId, cc->cycle_mark_neop); add_object_address(OperatorRelationId, cc->cycle_mark_neop, 0, context->addrs); + } /* fall through to examine substructure */ } else if (IsA(node, Query)) @@ -2163,6 +2345,7 @@ find_expr_references_walker(Node *node, switch (rte->rtekind) { case RTE_RELATION: + LockNotPinnedObject(RelationRelationId, rte->relid); add_object_address(RelationRelationId, rte->relid, 0, context->addrs); break; @@ -2215,12 +2398,18 @@ find_expr_references_walker(Node *node, rte = rt_fetch(query->resultRelation, query->rtable); if (rte->rtekind == RTE_RELATION) { + bool locked = false; foreach(lc, query->targetList) { TargetEntry *tle = (TargetEntry *) lfirst(lc); if (tle->resjunk) continue; /* ignore junk tlist items */ + if (!locked) + { + LockNotPinnedObject(RelationRelationId, rte->relid); + locked = true; + } add_object_address(RelationRelationId, rte->relid, tle->resno, context->addrs); } @@ -2232,6 +2421,7 @@ find_expr_references_walker(Node *node, */ foreach(lc, query->constraintDeps) { + LockNotPinnedObject(ConstraintRelationId, lfirst_oid(lc)); add_object_address(ConstraintRelationId, lfirst_oid(lc), 0, context->addrs); } @@ -2266,16 +2456,25 @@ find_expr_references_walker(Node *node, */ foreach(ct, rtfunc->funccoltypes) { + LockNotPinnedObject(TypeRelationId, lfirst_oid(ct)); add_object_address(TypeRelationId, lfirst_oid(ct), 0, context->addrs); } foreach(ct, rtfunc->funccolcollations) { Oid collid = lfirst_oid(ct); + bool locked = false; if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID) + { + if (!locked) + { + LockNotPinnedObject(CollationRelationId, collid); + locked = true; + } add_object_address(CollationRelationId, collid, 0, context->addrs); + } } } else if (IsA(node, TableFunc)) @@ -2288,22 +2487,32 @@ find_expr_references_walker(Node *node, */ foreach(ct, tf->coltypes) { + LockNotPinnedObject(TypeRelationId, lfirst_oid(ct)); add_object_address(TypeRelationId, lfirst_oid(ct), 0, context->addrs); } foreach(ct, tf->colcollations) { Oid collid = lfirst_oid(ct); + bool locked = false; if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID) + { + if (!locked) + { + LockNotPinnedObject(CollationRelationId, collid); + locked = true; + } add_object_address(CollationRelationId, collid, 0, context->addrs); + } } } else if (IsA(node, TableSampleClause)) { TableSampleClause *tsc = (TableSampleClause *) node; + LockNotPinnedObject(ProcedureRelationId, tsc->tsmhandler); add_object_address(ProcedureRelationId, tsc->tsmhandler, 0, context->addrs); /* fall through to examine arguments */ @@ -2354,9 +2563,12 @@ process_function_rte_ref(RangeTblEntry *rte, AttrNumber attnum, Assert(attnum - atts_done <= tupdesc->natts); if (OidIsValid(reltype)) /* can this fail? */ + { + LockNotPinnedObject(RelationRelationId, reltype); add_object_address(RelationRelationId, reltype, attnum - atts_done, context->addrs); + } return; } /* Nothing to do; function's result type is handled elsewhere */ diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 0078a12f26..e92c8363e0 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -844,6 +844,7 @@ AddNewAttributeTuples(Oid new_rel_oid, /* Add dependency info */ ObjectAddressSubSet(myself, RelationRelationId, new_rel_oid, i + 1); ObjectAddressSet(referenced, TypeRelationId, attr->atttypid); + LockNotPinnedObject(TypeRelationId, attr->atttypid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* The default collation is pinned, so don't bother recording it */ @@ -852,6 +853,7 @@ AddNewAttributeTuples(Oid new_rel_oid, { ObjectAddressSet(referenced, CollationRelationId, attr->attcollation); + LockNotPinnedObject(CollationRelationId, attr->attcollation); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } } @@ -1459,11 +1461,13 @@ heap_create_with_catalog(const char *relname, ObjectAddressSet(referenced, NamespaceRelationId, relnamespace); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(NamespaceRelationId, relnamespace); if (reloftypeid) { ObjectAddressSet(referenced, TypeRelationId, reloftypeid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, reloftypeid); } /* @@ -1477,6 +1481,7 @@ heap_create_with_catalog(const char *relname, { ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(AccessMethodRelationId, accessmtd); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); @@ -3390,6 +3395,7 @@ StorePartitionKey(Relation rel, { ObjectAddressSet(referenced, OperatorClassRelationId, partopclass[i]); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(OperatorClassRelationId, partopclass[i]); /* The default collation is pinned, so don't bother recording it */ if (OidIsValid(partcollation[i]) && @@ -3397,6 +3403,7 @@ StorePartitionKey(Relation rel, { ObjectAddressSet(referenced, CollationRelationId, partcollation[i]); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(CollationRelationId, partcollation[i]); } } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9162b9f81a..0ede0fd153 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1116,6 +1116,7 @@ index_create(Relation heapRelation, else { bool have_simple_col = false; + bool locked_object = false; addrs = new_object_addresses(); @@ -1128,6 +1129,12 @@ index_create(Relation heapRelation, heapRelationId, indexInfo->ii_IndexAttrNumbers[i]); add_exact_object_address(&referenced, addrs); + + if (!locked_object) + { + LockNotPinnedObject(RelationRelationId, heapRelationId); + locked_object = true; + } have_simple_col = true; } } @@ -1143,6 +1150,8 @@ index_create(Relation heapRelation, ObjectAddressSet(referenced, RelationRelationId, heapRelationId); add_exact_object_address(&referenced, addrs); + + LockNotPinnedObject(RelationRelationId, heapRelationId); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_AUTO); @@ -1158,9 +1167,13 @@ index_create(Relation heapRelation, if (OidIsValid(parentIndexRelid)) { ObjectAddressSet(referenced, RelationRelationId, parentIndexRelid); + + LockNotPinnedObject(RelationRelationId, parentIndexRelid); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, heapRelationId); + + LockNotPinnedObject(RelationRelationId, heapRelationId); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } @@ -1176,6 +1189,7 @@ index_create(Relation heapRelation, { ObjectAddressSet(referenced, CollationRelationId, collationIds[i]); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(CollationRelationId, collationIds[i]); } } @@ -1184,6 +1198,7 @@ index_create(Relation heapRelation, { ObjectAddressSet(referenced, OperatorClassRelationId, opclassIds[i]); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(OperatorClassRelationId, opclassIds[i]); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); @@ -1993,6 +2008,14 @@ index_constraint_create(Relation heapRelation, */ ObjectAddressSet(myself, ConstraintRelationId, conOid); ObjectAddressSet(idxaddr, RelationRelationId, indexRelationId); + + /* + * CommandCounterIncrement() here to ensure the new constraint entry is + * visible when LockNotPinnedObject() will check its existence before + * recording the dependencies. + */ + CommandCounterIncrement(); + LockNotPinnedObject(ConstraintRelationId, conOid); recordDependencyOn(&idxaddr, &myself, DEPENDENCY_INTERNAL); /* @@ -2004,9 +2027,12 @@ index_constraint_create(Relation heapRelation, ObjectAddress referenced; ObjectAddressSet(referenced, ConstraintRelationId, parentConstraintId); + LockNotPinnedObject(ConstraintRelationId, parentConstraintId); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(heapRelation)); + + LockNotPinnedObject(RelationRelationId, RelationGetRelid(heapRelation)); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 85a7b7e641..17c4085948 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -2590,6 +2590,63 @@ get_object_namespace(const ObjectAddress *address) return oid; } +/* + * ObjectByIdExist + * + * Return whether the given object exists. + * + * Works for most catalogs, if no special processing is needed. + */ +bool +ObjectByIdExist(const ObjectAddress *address) +{ + HeapTuple tuple; + int cache; + const ObjectPropertyType *property; + + property = get_object_property_data(address->classId); + + cache = property->oid_catcache_id; + + if (cache >= 0) + { + /* Fetch tuple from syscache. */ + tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId)); + + if (!HeapTupleIsValid(tuple)) + { + return false; + } + + ReleaseSysCache(tuple); + + return true; + } + else + { + Relation rel; + ScanKeyData skey[1]; + SysScanDesc scan; + + rel = table_open(address->classId, AccessShareLock); + + ScanKeyInit(&skey[0], + get_object_attnum_oid(address->classId), + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(address->objectId)); + + scan = systable_beginscan(rel, get_object_oid_index(address->classId), true, + NULL, 1, skey); + + /* we expect exactly one match */ + tuple = systable_getnext(scan); + systable_endscan(scan); + table_close(rel, AccessShareLock); + + return (HeapTupleIsValid(tuple)); + } +} + /* * Return ObjectType for the given object type as given by * getObjectTypeDescription; if no valid ObjectType code exists, but it's a diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 90fc7db949..a47e3c5507 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -748,12 +748,14 @@ AggregateCreate(const char *aggName, /* Depends on transition function */ ObjectAddressSet(referenced, ProcedureRelationId, transfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, transfn); /* Depends on final function, if any */ if (OidIsValid(finalfn)) { ObjectAddressSet(referenced, ProcedureRelationId, finalfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, finalfn); } /* Depends on combine function, if any */ @@ -761,6 +763,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, combinefn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, combinefn); } /* Depends on serialization function, if any */ @@ -768,6 +771,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, serialfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, serialfn); } /* Depends on deserialization function, if any */ @@ -775,6 +779,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, deserialfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, deserialfn); } /* Depends on forward transition function, if any */ @@ -782,6 +787,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, mtransfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, mtransfn); } /* Depends on inverse transition function, if any */ @@ -789,6 +795,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, minvtransfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, minvtransfn); } /* Depends on final function, if any */ @@ -796,6 +803,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, ProcedureRelationId, mfinalfn); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, mfinalfn); } /* Depends on sort operator, if any */ @@ -803,6 +811,7 @@ AggregateCreate(const char *aggName, { ObjectAddressSet(referenced, OperatorRelationId, sortop); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(OperatorRelationId, sortop); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c index 003ae70b4d..dcce454f00 100644 --- a/src/backend/catalog/pg_attrdef.c +++ b/src/backend/catalog/pg_attrdef.c @@ -178,6 +178,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, colobject.objectId = RelationGetRelid(rel); colobject.objectSubId = attnum; + LockNotPinnedObject(RelationRelationId, RelationGetRelid(rel)); recordDependencyOn(&defobject, &colobject, attgenerated ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO); diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c index 5a5b855d51..d3707e424c 100644 --- a/src/backend/catalog/pg_cast.c +++ b/src/backend/catalog/pg_cast.c @@ -97,16 +97,19 @@ CastCreate(Oid sourcetypeid, Oid targettypeid, /* dependency on source type */ ObjectAddressSet(referenced, TypeRelationId, sourcetypeid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, sourcetypeid); /* dependency on target type */ ObjectAddressSet(referenced, TypeRelationId, targettypeid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, targettypeid); /* dependency on function */ if (OidIsValid(funcid)) { ObjectAddressSet(referenced, ProcedureRelationId, funcid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, funcid); } /* dependencies on casts required for function */ @@ -114,11 +117,13 @@ CastCreate(Oid sourcetypeid, Oid targettypeid, { ObjectAddressSet(referenced, CastRelationId, incastid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(CastRelationId, incastid); } if (OidIsValid(outcastid)) { ObjectAddressSet(referenced, CastRelationId, outcastid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(CastRelationId, outcastid); } record_object_address_dependencies(&myself, addrs, behavior); diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c index 7f2f701229..78498b8c20 100644 --- a/src/backend/catalog/pg_collation.c +++ b/src/backend/catalog/pg_collation.c @@ -218,6 +218,7 @@ CollationCreate(const char *collname, Oid collnamespace, referenced.classId = NamespaceRelationId; referenced.objectId = collnamespace; referenced.objectSubId = 0; + LockNotPinnedObject(NamespaceRelationId, collnamespace); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 54f3fb50a5..8999c997f9 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -256,17 +256,26 @@ CreateConstraintEntry(const char *constraintName, if (constraintNTotalKeys > 0) { + bool locked_object = false; + for (i = 0; i < constraintNTotalKeys; i++) { ObjectAddressSubSet(relobject, RelationRelationId, relId, constraintKey[i]); add_exact_object_address(&relobject, addrs_auto); + + if (!locked_object) + { + LockNotPinnedObject(RelationRelationId, relId); + locked_object = true; + } } } else { ObjectAddressSet(relobject, RelationRelationId, relId); add_exact_object_address(&relobject, addrs_auto); + LockNotPinnedObject(RelationRelationId, relId); } } @@ -279,6 +288,7 @@ CreateConstraintEntry(const char *constraintName, ObjectAddressSet(domobject, TypeRelationId, domainId); add_exact_object_address(&domobject, addrs_auto); + LockNotPinnedObject(TypeRelationId, domainId); } record_object_address_dependencies(&conobject, addrs_auto, @@ -298,17 +308,26 @@ CreateConstraintEntry(const char *constraintName, if (foreignNKeys > 0) { + bool locked_object = false; + for (i = 0; i < foreignNKeys; i++) { ObjectAddressSubSet(relobject, RelationRelationId, foreignRelId, foreignKey[i]); add_exact_object_address(&relobject, addrs_normal); + + if (!locked_object) + { + LockNotPinnedObject(RelationRelationId, foreignRelId); + locked_object = true; + } } } else { ObjectAddressSet(relobject, RelationRelationId, foreignRelId); add_exact_object_address(&relobject, addrs_normal); + LockNotPinnedObject(RelationRelationId, foreignRelId); } } @@ -324,6 +343,7 @@ CreateConstraintEntry(const char *constraintName, ObjectAddressSet(relobject, RelationRelationId, indexRelId); add_exact_object_address(&relobject, addrs_normal); + LockNotPinnedObject(RelationRelationId, indexRelId); } if (foreignNKeys > 0) @@ -343,15 +363,18 @@ CreateConstraintEntry(const char *constraintName, { oprobject.objectId = pfEqOp[i]; add_exact_object_address(&oprobject, addrs_normal); + LockNotPinnedObject(OperatorRelationId, pfEqOp[i]); if (ppEqOp[i] != pfEqOp[i]) { oprobject.objectId = ppEqOp[i]; add_exact_object_address(&oprobject, addrs_normal); + LockNotPinnedObject(OperatorRelationId, ppEqOp[i]); } if (ffEqOp[i] != pfEqOp[i]) { oprobject.objectId = ffEqOp[i]; add_exact_object_address(&oprobject, addrs_normal); + LockNotPinnedObject(OperatorRelationId, ffEqOp[i]); } } } @@ -863,9 +886,12 @@ ConstraintSetParentConstraint(Oid childConstrId, ObjectAddressSet(depender, ConstraintRelationId, childConstrId); ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId); + LockNotPinnedObject(ConstraintRelationId, parentConstrId); recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, childTableId); + + LockNotPinnedObject(RelationRelationId, childTableId); recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC); } else diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index 0770878eac..25881654d6 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -116,12 +116,14 @@ ConversionCreate(const char *conname, Oid connamespace, referenced.classId = ProcedureRelationId; referenced.objectId = conproc; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, conproc); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on namespace */ referenced.classId = NamespaceRelationId; referenced.objectId = connamespace; referenced.objectSubId = 0; + LockNotPinnedObject(NamespaceRelationId, connamespace); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index 2b4514e8a3..d9760d7d05 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -20,19 +20,20 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/pg_auth_members.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" #include "catalog/pg_extension.h" #include "catalog/partition.h" #include "commands/extension.h" #include "miscadmin.h" +#include "storage/lmgr.h" +#include "storage/lock.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/rel.h" -static bool isObjectPinned(const ObjectAddress *object); - /* * Record a dependency between 2 objects via their respective objectAddress. @@ -99,6 +100,37 @@ recordMultipleDependencies(const ObjectAddress *depender, slot_init_count = 0; for (i = 0; i < nreferenced; i++, referenced++) { +#ifdef USE_ASSERT_CHECKING + if (!isObjectPinned(referenced)) + { + if (referenced->classId != RelationRelationId) + { + LOCKTAG tag; + + SET_LOCKTAG_OBJECT(tag, + MyDatabaseId, + referenced->classId, + referenced->objectId, + 0); + /* assert the referenced object is locked */ + Assert(LockHeldByMe(&tag, AccessShareLock, false)); + } + else + { + Assert(!IsSharedRelation(referenced->objectId)); + + /* + * Assert the referenced object is locked if it should be + * visible (see the comment related to LockNotPinnedObject() + * in TypeCreate()). + */ + Assert(!ObjectByIdExist(referenced) || + CheckRelationOidLockedByMe(referenced->objectId, + AccessShareLock, true)); + } + } +#endif + /* * If the referenced object is pinned by the system, there's no real * need to record dependencies on it. This saves lots of space in @@ -238,6 +270,7 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object, extension.objectId = CurrentExtensionObject; extension.objectSubId = 0; + LockNotPinnedObject(ExtensionRelationId, CurrentExtensionObject); recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION); } } @@ -705,7 +738,7 @@ changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, * The passed subId, if any, is ignored; we assume that only whole objects * are pinned (and that this implies pinning their components). */ -static bool +bool isObjectPinned(const ObjectAddress *object) { return IsPinnedObject(object->classId, object->objectId); diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 65b45a424a..e8374eec88 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -251,6 +251,16 @@ OperatorShellMake(const char *operatorName, values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid); + /* Lock dependent objects */ + if (OidIsValid(operatorNamespace)) + LockNotPinnedObject(NamespaceRelationId, operatorNamespace); + + if (OidIsValid(leftTypeId)) + LockNotPinnedObject(TypeRelationId, leftTypeId); + + if (OidIsValid(rightTypeId)) + LockNotPinnedObject(TypeRelationId, rightTypeId); + /* * create a new operator tuple */ @@ -513,6 +523,15 @@ OperatorCreate(const char *operatorName, CatalogTupleInsert(pg_operator_desc, tup); } + /* Lock dependent objects */ + LockNotPinnedObject(NamespaceRelationId, operatorNamespace); + LockNotPinnedObject(TypeRelationId, leftTypeId); + LockNotPinnedObject(TypeRelationId, rightTypeId); + LockNotPinnedObject(TypeRelationId, operResultType); + LockNotPinnedObject(ProcedureRelationId, procedureId); + LockNotPinnedObject(ProcedureRelationId, restrictionId); + LockNotPinnedObject(ProcedureRelationId, joinId); + /* Add dependencies for the entry */ address = makeOperatorDependencies(tup, true, isUpdate); diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 528c17cd7f..116e524390 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -593,6 +593,13 @@ ProcedureCreate(const char *procedureName, if (is_update) deleteDependencyRecordsFor(ProcedureRelationId, retval, true); + /* + * CommandCounterIncrement() here to ensure the new function entry is + * visible when LockNotPinnedObject() will check its existence before + * recording the dependencies. + */ + CommandCounterIncrement(); + addrs = new_object_addresses(); ObjectAddressSet(myself, ProcedureRelationId, retval); @@ -600,20 +607,24 @@ ProcedureCreate(const char *procedureName, /* dependency on namespace */ ObjectAddressSet(referenced, NamespaceRelationId, procNamespace); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(NamespaceRelationId, procNamespace); /* dependency on implementation language */ ObjectAddressSet(referenced, LanguageRelationId, languageObjectId); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(LanguageRelationId, languageObjectId); /* dependency on return type */ ObjectAddressSet(referenced, TypeRelationId, returnType); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, returnType); /* dependency on transform used by return type, if any */ if ((trfid = get_transform_oid(returnType, languageObjectId, true))) { ObjectAddressSet(referenced, TransformRelationId, trfid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TransformRelationId, trfid); } /* dependency on parameter types */ @@ -621,12 +632,14 @@ ProcedureCreate(const char *procedureName, { ObjectAddressSet(referenced, TypeRelationId, allParams[i]); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, allParams[i]); /* dependency on transform used by parameter type, if any */ if ((trfid = get_transform_oid(allParams[i], languageObjectId, true))) { ObjectAddressSet(referenced, TransformRelationId, trfid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TransformRelationId, trfid); } } @@ -635,6 +648,7 @@ ProcedureCreate(const char *procedureName, { ObjectAddressSet(referenced, ProcedureRelationId, prosupport); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, prosupport); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); @@ -674,9 +688,6 @@ ProcedureCreate(const char *procedureName, ArrayType *set_items = NULL; int save_nestlevel = 0; - /* Advance command counter so new tuple can be seen by validator */ - CommandCounterIncrement(); - /* * Set per-function configuration parameters so that the validation is * done with the environment the function expects. However, if diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 7e5e357fd9..35e7425ac6 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -395,6 +395,7 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri, referenced; List *relids = NIL; int i; + bool locked = false; rel = table_open(PublicationRelRelationId, RowExclusiveLock); @@ -457,10 +458,13 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri, /* Add dependency on the publication */ ObjectAddressSet(referenced, PublicationRelationId, pubid); + LockNotPinnedObject(PublicationRelationId, pubid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* Add dependency on the relation */ ObjectAddressSet(referenced, RelationRelationId, relid); + + LockNotPinnedObject(RelationRelationId, relid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* Add dependency on the objects mentioned in the qualifications */ @@ -474,6 +478,11 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri, while ((i = bms_next_member(attnums, i)) >= 0) { ObjectAddressSubSet(referenced, RelationRelationId, relid, i); + if (!locked) + { + LockNotPinnedObject(RelationRelationId, relid); + locked = true; + } recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -643,10 +652,12 @@ publication_add_schema(Oid pubid, Oid schemaid, bool if_not_exists) /* Add dependency on the publication */ ObjectAddressSet(referenced, PublicationRelationId, pubid); + LockNotPinnedObject(PublicationRelationId, pubid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* Add dependency on the schema */ ObjectAddressSet(referenced, NamespaceRelationId, schemaid); + LockNotPinnedObject(NamespaceRelationId, schemaid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* Close the table */ diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c index 501a6ba410..e5b5a0b6f8 100644 --- a/src/backend/catalog/pg_range.c +++ b/src/backend/catalog/pg_range.c @@ -70,26 +70,31 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ObjectAddressSet(referenced, TypeRelationId, rangeSubType); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, rangeSubType); ObjectAddressSet(referenced, OperatorClassRelationId, rangeSubOpclass); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(OperatorClassRelationId, rangeSubOpclass); if (OidIsValid(rangeCollation)) { ObjectAddressSet(referenced, CollationRelationId, rangeCollation); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(CollationRelationId, rangeCollation); } if (OidIsValid(rangeCanonical)) { ObjectAddressSet(referenced, ProcedureRelationId, rangeCanonical); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, rangeCanonical); } if (OidIsValid(rangeSubDiff)) { ObjectAddressSet(referenced, ProcedureRelationId, rangeSubDiff); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, rangeSubDiff); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); @@ -99,6 +104,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, referencing.classId = TypeRelationId; referencing.objectId = multirangeTypeOid; referencing.objectSubId = 0; + LockNotPinnedObject(TypeRelationId, rangeTypeOid); recordDependencyOn(&referencing, &myself, DEPENDENCY_INTERNAL); table_close(pg_range, RowExclusiveLock); diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 395dec8ed8..82ee7bc2e3 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -157,6 +157,12 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) * Create dependencies. We can/must skip this in bootstrap mode. */ if (!IsBootstrapProcessingMode()) + { + /* Lock dependent objects */ + LockNotPinnedObject(NamespaceRelationId, typeNamespace); + LockNotPinnedObject(ProcedureRelationId, F_SHELL_IN); + LockNotPinnedObject(ProcedureRelationId, F_SHELL_OUT); + GenerateTypeDependencies(tup, pg_type_desc, NULL, @@ -166,6 +172,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) false, true, /* make extension dependency */ false); + } /* Post creation hook for new shell type */ InvokeObjectPostCreateHook(TypeRelationId, typoid, 0); @@ -494,6 +501,37 @@ TypeCreate(Oid newTypeOid, * Create dependencies. We can/must skip this in bootstrap mode. */ if (!IsBootstrapProcessingMode()) + { + /* + * CommandCounterIncrement() here to ensure the new type entry is + * visible when LockNotPinnedObject() will check its existence before + * recording the dependencies. + */ + CommandCounterIncrement(); + + /* Lock dependent objects */ + LockNotPinnedObject(NamespaceRelationId, typeNamespace); + LockNotPinnedObject(ProcedureRelationId, inputProcedure); + LockNotPinnedObject(ProcedureRelationId, outputProcedure); + LockNotPinnedObject(ProcedureRelationId, receiveProcedure); + LockNotPinnedObject(ProcedureRelationId, sendProcedure); + LockNotPinnedObject(ProcedureRelationId, typmodinProcedure); + LockNotPinnedObject(ProcedureRelationId, typmodoutProcedure); + LockNotPinnedObject(ProcedureRelationId, analyzeProcedure); + LockNotPinnedObject(ProcedureRelationId, subscriptProcedure); + LockNotPinnedObject(TypeRelationId, baseType); + LockNotPinnedObject(CollationRelationId, typeCollation); + LockNotPinnedObject(TypeRelationId, elementType); + + /* + * No need to call LockRelationOid() (through LockNotPinnedObject()) + * on relationOid as relationOid is set to an InvalidOid or to a new + * Oid not added to pg_class yet (In heap_create_with_catalog(), + * AddNewRelationType() is called before AddNewRelationTuple()). + */ + if (relationKind == RELKIND_COMPOSITE_TYPE) + LockNotPinnedObject(TypeRelationId, typeObjectId); + GenerateTypeDependencies(tup, pg_type_desc, (defaultTypeBin ? @@ -505,6 +543,7 @@ TypeCreate(Oid newTypeOid, isDependentType, true, /* make extension dependency */ rebuildDeps); + } /* Post creation hook for new type */ InvokeObjectPostCreateHook(TypeRelationId, typeObjectId, 0); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index ad3082c62a..039c824dab 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -383,6 +383,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, toastobject.objectId = toast_relid; toastobject.objectSubId = 0; + LockNotPinnedObject(RelationRelationId, relOid); recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL); } diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 4f99ebb447..57e86f576a 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -501,7 +501,10 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre currexts = getAutoExtensionsOfObject(address.classId, address.objectId); if (!list_member_oid(currexts, refAddr.objectId)) + { + LockNotPinnedObject(refAddr.classId, refAddr.objectId); recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION); + } } return address; @@ -807,6 +810,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) pfree(replaces); /* update dependency to point to the new schema */ + LockNotPinnedObject(NamespaceRelationId, nspOid); if (changeDependencyFor(classId, objid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "could not change schema dependency for object %u", diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c index aaa0f9a1dc..8616a7c9fa 100644 --- a/src/backend/commands/amcmds.c +++ b/src/backend/commands/amcmds.c @@ -104,6 +104,7 @@ CreateAccessMethod(CreateAmStmt *stmt) referenced.objectId = amhandler; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, amhandler); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOnCurrentExtension(&myself, false); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index ae0863d9a2..f30ba63ee1 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -1271,6 +1271,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, */ if (relam1 != relam2) { + LockNotPinnedObject(AccessMethodRelationId, relam2); if (changeDependencyFor(RelationRelationId, r1, AccessMethodRelationId, @@ -1279,6 +1280,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, elog(ERROR, "could not change access method dependency for relation \"%s.%s\"", get_namespace_name(get_rel_namespace(r1)), get_rel_name(r1)); + + LockNotPinnedObject(AccessMethodRelationId, relam1); if (changeDependencyFor(RelationRelationId, r2, AccessMethodRelationId, @@ -1380,6 +1383,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, { baseobject.objectId = r1; toastobject.objectId = relform1->reltoastrelid; + + LockNotPinnedObject(RelationRelationId, r1); recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL); } @@ -1388,6 +1393,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, { baseobject.objectId = r2; toastobject.objectId = relform2->reltoastrelid; + + LockNotPinnedObject(RelationRelationId, r2); recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL); } diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index a586d246ec..5359aaf239 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -327,6 +327,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO referenced.classId = ProcedureRelationId; referenced.objectId = funcoid; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, funcoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* Depend on extension, if any. */ diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index ec71761377..6656937126 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2031,6 +2031,7 @@ InsertExtensionTuple(const char *extName, Oid extOwner, ObjectAddressSet(nsp, NamespaceRelationId, schemaOid); add_exact_object_address(&nsp, refobjs); + LockNotPinnedObject(NamespaceRelationId, schemaOid); foreach(lc, requiredExtensions) { @@ -2039,6 +2040,7 @@ InsertExtensionTuple(const char *extName, Oid extOwner, ObjectAddressSet(otherext, ExtensionRelationId, reqext); add_exact_object_address(&otherext, refobjs); + LockNotPinnedObject(ExtensionRelationId, reqext); } /* Record all of them (this includes duplicate elimination) */ @@ -3075,6 +3077,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o table_close(extRel, RowExclusiveLock); /* update dependency to point to the new schema */ + LockNotPinnedObject(NamespaceRelationId, nspOid); if (changeDependencyFor(ExtensionRelationId, extensionOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "could not change schema dependency for extension %s", @@ -3365,6 +3368,7 @@ ApplyExtensionUpdates(Oid extensionOid, otherext.objectId = reqext; otherext.objectSubId = 0; + LockNotPinnedObject(ExtensionRelationId, reqext); recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL); } @@ -3521,6 +3525,7 @@ ExecAlterExtensionContentsRecurse(AlterExtensionContentsStmt *stmt, /* * OK, add the dependency. */ + LockNotPinnedObject(extension.classId, extension.objectId); recordDependencyOn(&object, &extension, DEPENDENCY_EXTENSION); /* diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index cf61bbac1f..735bca486c 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -642,6 +642,7 @@ CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt) referenced.classId = ProcedureRelationId; referenced.objectId = fdwhandler; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, fdwhandler); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -650,6 +651,7 @@ CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt) referenced.classId = ProcedureRelationId; referenced.objectId = fdwvalidator; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, fdwvalidator); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -811,6 +813,7 @@ AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) referenced.classId = ProcedureRelationId; referenced.objectId = fdwhandler; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, fdwhandler); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -819,6 +822,7 @@ AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) referenced.classId = ProcedureRelationId; referenced.objectId = fdwvalidator; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, fdwvalidator); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } } @@ -951,6 +955,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) referenced.classId = ForeignDataWrapperRelationId; referenced.objectId = fdw->fdwid; referenced.objectSubId = 0; + LockNotPinnedObject(ForeignDataWrapperRelationId, fdw->fdwid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId); @@ -1195,6 +1200,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt) referenced.classId = ForeignServerRelationId; referenced.objectId = srv->serverid; referenced.objectSubId = 0; + LockNotPinnedObject(ForeignServerRelationId, srv->serverid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); if (OidIsValid(useId)) @@ -1472,6 +1478,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid) referenced.classId = ForeignServerRelationId; referenced.objectId = server->serverid; referenced.objectSubId = 0; + LockNotPinnedObject(ForeignServerRelationId, server->serverid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); table_close(ftrel, RowExclusiveLock); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index d43b89d3ef..4b0c203acb 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1446,6 +1446,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) /* Add or replace dependency on support function */ if (OidIsValid(procForm->prosupport)) { + LockNotPinnedObject(ProcedureRelationId, newsupport); if (changeDependencyFor(ProcedureRelationId, funcOid, ProcedureRelationId, procForm->prosupport, newsupport) != 1) @@ -1459,6 +1460,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) referenced.classId = ProcedureRelationId; referenced.objectId = newsupport; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, newsupport); recordDependencyOn(&address, &referenced, DEPENDENCY_NORMAL); } @@ -1975,21 +1977,25 @@ CreateTransform(CreateTransformStmt *stmt) /* dependency on language */ ObjectAddressSet(referenced, LanguageRelationId, langid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(LanguageRelationId, langid); /* dependency on type */ ObjectAddressSet(referenced, TypeRelationId, typeid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(TypeRelationId, typeid); /* dependencies on functions */ if (OidIsValid(fromsqlfuncid)) { ObjectAddressSet(referenced, ProcedureRelationId, fromsqlfuncid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, fromsqlfuncid); } if (OidIsValid(tosqlfuncid)) { ObjectAddressSet(referenced, ProcedureRelationId, tosqlfuncid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, tosqlfuncid); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 2f652463e3..2799742826 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -4517,8 +4517,10 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) ObjectAddressSet(parentIdx, RelationRelationId, parentOid); ObjectAddressSet(partitionTbl, RelationRelationId, partitionIdx->rd_index->indrelid); + LockNotPinnedObject(RelationRelationId, parentOid); recordDependencyOn(&partIdx, &parentIdx, DEPENDENCY_PARTITION_PRI); + LockNotPinnedObject(RelationRelationId, partitionIdx->rd_index->indrelid); recordDependencyOn(&partIdx, &partitionTbl, DEPENDENCY_PARTITION_SEC); } diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index b8b5c147c5..e70afd216c 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -298,12 +298,14 @@ CreateOpFamily(CreateOpFamilyStmt *stmt, const char *opfname, referenced.classId = AccessMethodRelationId; referenced.objectId = amoid; referenced.objectSubId = 0; + LockNotPinnedObject(AccessMethodRelationId, amoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* dependency on namespace */ referenced.classId = NamespaceRelationId; referenced.objectId = namespaceoid; referenced.objectSubId = 0; + LockNotPinnedObject(NamespaceRelationId, namespaceoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* dependency on owner */ @@ -725,18 +727,21 @@ DefineOpClass(CreateOpClassStmt *stmt) referenced.classId = NamespaceRelationId; referenced.objectId = namespaceoid; referenced.objectSubId = 0; + LockNotPinnedObject(NamespaceRelationId, namespaceoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* dependency on opfamily */ referenced.classId = OperatorFamilyRelationId; referenced.objectId = opfamilyoid; referenced.objectSubId = 0; + LockNotPinnedObject(OperatorFamilyRelationId, opfamilyoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* dependency on indexed datatype */ referenced.classId = TypeRelationId; referenced.objectId = typeoid; referenced.objectSubId = 0; + LockNotPinnedObject(TypeRelationId, typeoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* dependency on storage datatype */ @@ -745,6 +750,7 @@ DefineOpClass(CreateOpClassStmt *stmt) referenced.classId = TypeRelationId; referenced.objectId = storageoid; referenced.objectSubId = 0; + LockNotPinnedObject(TypeRelationId, storageoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -1486,6 +1492,13 @@ storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, heap_freetuple(tup); + /* + * CommandCounterIncrement() here to ensure the new operator entry is + * visible when LockNotPinnedObject() will check its existence before + * recording the dependencies. + */ + CommandCounterIncrement(); + /* Make its dependencies */ myself.classId = AccessMethodOperatorRelationId; myself.objectId = entryoid; @@ -1496,6 +1509,7 @@ storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, referenced.objectSubId = 0; /* see comments in amapi.h about dependency strength */ + LockNotPinnedObject(OperatorRelationId, op->object); recordDependencyOn(&myself, &referenced, op->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO); @@ -1504,6 +1518,7 @@ storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, referenced.objectId = op->refobjid; referenced.objectSubId = 0; + LockNotPinnedObject(referenced.classId, op->refobjid); recordDependencyOn(&myself, &referenced, op->ref_is_hard ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO); @@ -1514,6 +1529,7 @@ storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, referenced.objectId = op->sortfamily; referenced.objectSubId = 0; + LockNotPinnedObject(OperatorFamilyRelationId, op->sortfamily); recordDependencyOn(&myself, &referenced, op->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO); } @@ -1597,6 +1613,7 @@ storeProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, referenced.objectSubId = 0; /* see comments in amapi.h about dependency strength */ + LockNotPinnedObject(ProcedureRelationId, proc->object); recordDependencyOn(&myself, &referenced, proc->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO); @@ -1605,6 +1622,7 @@ storeProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, referenced.objectId = proc->refobjid; referenced.objectSubId = 0; + LockNotPinnedObject(referenced.classId, proc->refobjid); recordDependencyOn(&myself, &referenced, proc->ref_is_hard ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO); diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 5872a3e192..58a69e7cc2 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -33,6 +33,7 @@ #include "access/htup_details.h" #include "access/table.h" +#include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" @@ -656,11 +657,15 @@ AlterOperator(AlterOperatorStmt *stmt) { replaces[Anum_pg_operator_oprrest - 1] = true; values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(restrictionOid); + if (OidIsValid(restrictionOid)) + LockNotPinnedObject(ProcedureRelationId, restrictionOid); } if (updateJoin) { replaces[Anum_pg_operator_oprjoin - 1] = true; values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(joinOid); + if (OidIsValid(joinOid)) + LockNotPinnedObject(ProcedureRelationId, joinOid); } if (OidIsValid(commutatorOid)) { @@ -688,6 +693,31 @@ AlterOperator(AlterOperatorStmt *stmt) CatalogTupleUpdate(catalog, &tup->t_self, tup); + + /* Lock dependent objects */ + oprForm = (Form_pg_operator) GETSTRUCT(tup); + + if (OidIsValid(oprForm->oprnamespace)) + LockNotPinnedObject(NamespaceRelationId, oprForm->oprnamespace); + + if (OidIsValid(oprForm->oprleft)) + LockNotPinnedObject(TypeRelationId, oprForm->oprleft); + + if (OidIsValid(oprForm->oprright)) + LockNotPinnedObject(TypeRelationId, oprForm->oprright); + + if (OidIsValid(oprForm->oprresult)) + LockNotPinnedObject(TypeRelationId, oprForm->oprresult); + + if (OidIsValid(oprForm->oprcode)) + LockNotPinnedObject(ProcedureRelationId, oprForm->oprcode); + + if (OidIsValid(oprForm->oprrest)) + LockNotPinnedObject(ProcedureRelationId, oprForm->oprrest); + + if (OidIsValid(oprForm->oprjoin)) + LockNotPinnedObject(ProcedureRelationId, oprForm->oprjoin); + address = makeOperatorDependencies(tup, false, true); if (OidIsValid(commutatorOid) || OidIsValid(negatorOid)) diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index 6ff3eba824..9da98cbeec 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -722,6 +722,7 @@ CreatePolicy(CreatePolicyStmt *stmt) myself.objectId = policy_id; myself.objectSubId = 0; + LockNotPinnedObject(RelationRelationId, table_id); recordDependencyOn(&myself, &target, DEPENDENCY_AUTO); recordDependencyOnExpr(&myself, qual, qual_pstate->p_rtable, @@ -1053,6 +1054,7 @@ AlterPolicy(AlterPolicyStmt *stmt) myself.objectId = policy_id; myself.objectSubId = 0; + LockNotPinnedObject(RelationRelationId, table_id); recordDependencyOn(&myself, &target, DEPENDENCY_AUTO); recordDependencyOnExpr(&myself, qual, qual_parse_rtable, DEPENDENCY_NORMAL); diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 881f90017e..fadfd9064f 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -190,12 +190,14 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) /* dependency on the PL handler function */ ObjectAddressSet(referenced, ProcedureRelationId, handlerOid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, handlerOid); /* dependency on the inline handler function, if any */ if (OidIsValid(inlineOid)) { ObjectAddressSet(referenced, ProcedureRelationId, inlineOid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, inlineOid); } /* dependency on the validator function, if any */ @@ -203,6 +205,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) { ObjectAddressSet(referenced, ProcedureRelationId, valOid); add_exact_object_address(&referenced, addrs); + LockNotPinnedObject(ProcedureRelationId, valOid); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 0188e8bbd5..d7ba2e59e6 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1691,6 +1691,8 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity) depobject.classId = RelationRelationId; depobject.objectId = RelationGetRelid(seqrel); depobject.objectSubId = 0; + + LockNotPinnedObject(RelationRelationId, RelationGetRelid(tablerel)); recordDependencyOn(&depobject, &refobject, deptype); } diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index 1db3ef69d2..9f0b03388a 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -88,6 +88,7 @@ CreateStatistics(CreateStatsStmt *stmt) bool build_mcv; bool build_expressions; bool requested_type = false; + bool locked_object = false; int i; ListCell *cell; ListCell *cell2; @@ -536,6 +537,12 @@ CreateStatistics(CreateStatsStmt *stmt) for (i = 0; i < nattnums; i++) { ObjectAddressSubSet(parentobject, RelationRelationId, relid, attnums[i]); + + if (!locked_object) + { + LockNotPinnedObject(RelationRelationId, relid); + locked_object = true; + } recordDependencyOn(&myself, &parentobject, DEPENDENCY_AUTO); } @@ -553,6 +560,8 @@ CreateStatistics(CreateStatsStmt *stmt) if (!nattnums) { ObjectAddressSet(parentobject, RelationRelationId, relid); + + LockNotPinnedObject(RelationRelationId, relid); recordDependencyOn(&myself, &parentobject, DEPENDENCY_AUTO); } @@ -573,6 +582,7 @@ CreateStatistics(CreateStatsStmt *stmt) * than the underlying table(s). */ ObjectAddressSet(parentobject, NamespaceRelationId, namespaceId); + LockNotPinnedObject(NamespaceRelationId, namespaceId); recordDependencyOn(&myself, &parentobject, DEPENDENCY_NORMAL); recordDependencyOnOwner(StatisticExtRelationId, statoid, stxowner); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e14bc0c054..ea775bf531 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3445,6 +3445,7 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid, childobject.objectId = relationId; childobject.objectSubId = 0; + LockNotPinnedObject(RelationRelationId, parentOid); recordDependencyOn(&childobject, &parentobject, child_dependency_type(child_is_partition)); @@ -7367,7 +7368,9 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* * Add needed dependency entries for the new column. */ + LockNotPinnedObject(TypeRelationId, attribute->atttypid); add_column_datatype_dependency(myrelid, newattnum, attribute->atttypid); + LockNotPinnedObject(CollationRelationId, attribute->attcollation); add_column_collation_dependency(myrelid, newattnum, attribute->attcollation); /* @@ -10311,11 +10314,16 @@ addFkConstraint(addFkConstraintSides fkside, Assert(fkside != addFkBothSides); if (fkside == addFkReferencedSide) + { + LockNotPinnedObject(ConstraintRelationId, parentConstr); recordDependencyOn(&address, &referenced, DEPENDENCY_INTERNAL); + } else { + LockNotPinnedObject(ConstraintRelationId, parentConstr); recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(rel)); + LockNotPinnedObject(RelationRelationId, RelationGetRelid(rel)); recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_SEC); } } @@ -13495,7 +13503,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, table_close(attrelation, RowExclusiveLock); /* Install dependencies on new datatype and collation */ + LockNotPinnedObject(TypeRelationId, targettype); add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype); + LockNotPinnedObject(CollationRelationId, targetcollid); add_column_collation_dependency(RelationGetRelid(rel), attnum, targetcollid); /* @@ -15058,6 +15068,7 @@ ATExecSetAccessMethodNoStorage(Relation rel, Oid newAccessMethodId) */ ObjectAddressSet(relobj, RelationRelationId, reloid); ObjectAddressSet(referenced, AccessMethodRelationId, rd_rel->relam); + LockNotPinnedObject(AccessMethodRelationId, rd_rel->relam); recordDependencyOn(&relobj, &referenced, DEPENDENCY_NORMAL); } else if (OidIsValid(oldAccessMethodId) && @@ -15077,6 +15088,7 @@ ATExecSetAccessMethodNoStorage(Relation rel, Oid newAccessMethodId) OidIsValid(rd_rel->relam)); /* Both are valid, so update the dependency */ + LockNotPinnedObject(AccessMethodRelationId, rd_rel->relam); changeDependencyFor(RelationRelationId, reloid, AccessMethodRelationId, oldAccessMethodId, rd_rel->relam); @@ -16679,6 +16691,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) typeobj.classId = TypeRelationId; typeobj.objectId = typeid; typeobj.objectSubId = 0; + LockNotPinnedObject(TypeRelationId, typeid); recordDependencyOn(&tableobj, &typeobj, DEPENDENCY_NORMAL); /* Update pg_class.reloftype */ @@ -17445,14 +17458,17 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid, /* Update dependency on schema if caller said so */ - if (hasDependEntry && - changeDependencyFor(RelationRelationId, + if (hasDependEntry) + { + LockNotPinnedObject(NamespaceRelationId, newNspOid); + if (changeDependencyFor(RelationRelationId, relOid, NamespaceRelationId, oldNspOid, newNspOid) != 1) - elog(ERROR, "could not change schema dependency for relation \"%s\"", - NameStr(classForm->relname)); + elog(ERROR, "could not change schema dependency for relation \"%s\"", + NameStr(classForm->relname)); + } } else UnlockTuple(classRel, &classTup->t_self, InplaceUpdateTupleLock); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 09356e46d1..f1782f0c65 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -1019,8 +1019,6 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, ((Form_pg_class) GETSTRUCT(tuple))->relhastriggers = true; CatalogTupleUpdate(pgrel, &tuple->t_self, tuple); - - CommandCounterIncrement(); } else CacheInvalidateRelcacheByTuple(tuple); @@ -1028,6 +1026,13 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, heap_freetuple(tuple); table_close(pgrel, RowExclusiveLock); + /* + * CommandCounterIncrement() here to ensure the new trigger entry is + * visible when LockNotPinnedObject() will check its existence before + * recording the dependencies. + */ + CommandCounterIncrement(); + /* * If we're replacing a trigger, flush all the old dependencies before * recording new ones. @@ -1046,6 +1051,7 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, referenced.classId = ProcedureRelationId; referenced.objectId = funcoid; referenced.objectSubId = 0; + LockNotPinnedObject(ProcedureRelationId, funcoid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); if (isInternal && OidIsValid(constraintOid)) @@ -1059,6 +1065,7 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, referenced.classId = ConstraintRelationId; referenced.objectId = constraintOid; referenced.objectSubId = 0; + LockNotPinnedObject(ConstraintRelationId, constraintOid); recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); } else @@ -1071,6 +1078,8 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, referenced.classId = RelationRelationId; referenced.objectId = RelationGetRelid(rel); referenced.objectSubId = 0; + + LockNotPinnedObject(RelationRelationId, RelationGetRelid(rel)); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); if (OidIsValid(constrrelid)) @@ -1078,6 +1087,8 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, referenced.classId = RelationRelationId; referenced.objectId = constrrelid; referenced.objectSubId = 0; + + LockNotPinnedObject(RelationRelationId, constrrelid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); } /* Not possible to have an index dependency in this case */ @@ -1092,6 +1103,7 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, referenced.classId = ConstraintRelationId; referenced.objectId = constraintOid; referenced.objectSubId = 0; + LockNotPinnedObject(TriggerRelationId, trigoid); recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL); } @@ -1101,8 +1113,11 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, if (OidIsValid(parentTriggerOid)) { ObjectAddressSet(referenced, TriggerRelationId, parentTriggerOid); + LockNotPinnedObject(TriggerRelationId, parentTriggerOid); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(rel)); + + LockNotPinnedObject(RelationRelationId, RelationGetRelid(rel)); recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } } @@ -1111,12 +1126,19 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, if (columns != NULL) { int i; + bool locked_object = false; referenced.classId = RelationRelationId; referenced.objectId = RelationGetRelid(rel); for (i = 0; i < ncolumns; i++) { referenced.objectSubId = columns[i]; + + if (!locked_object) + { + LockNotPinnedObject(RelationRelationId, RelationGetRelid(rel)); + locked_object = true; + } recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } } @@ -1256,9 +1278,12 @@ TriggerSetParentTrigger(Relation trigRel, ObjectAddressSet(depender, TriggerRelationId, childTrigId); ObjectAddressSet(referenced, TriggerRelationId, parentTrigId); + LockNotPinnedObject(TriggerRelationId, parentTrigId); recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI); ObjectAddressSet(referenced, RelationRelationId, childTableId); + + LockNotPinnedObject(RelationRelationId, childTableId); recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC); } else diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index b7b5019f1e..1b90e187ea 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -214,6 +214,7 @@ DefineTSParser(List *names, List *parameters) namestrcpy(&pname, prsname); values[Anum_pg_ts_parser_prsname - 1] = NameGetDatum(&pname); values[Anum_pg_ts_parser_prsnamespace - 1] = ObjectIdGetDatum(namespaceoid); + LockNotPinnedObject(NamespaceRelationId, namespaceoid); /* * loop over the definition list and extract the information we need. @@ -224,28 +225,48 @@ DefineTSParser(List *names, List *parameters) if (strcmp(defel->defname, "start") == 0) { + Oid procoid; + values[Anum_pg_ts_parser_prsstart - 1] = get_ts_parser_func(defel, Anum_pg_ts_parser_prsstart); + procoid = DatumGetObjectId(values[Anum_pg_ts_parser_prsstart - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else if (strcmp(defel->defname, "gettoken") == 0) { + Oid procoid; + values[Anum_pg_ts_parser_prstoken - 1] = get_ts_parser_func(defel, Anum_pg_ts_parser_prstoken); + procoid = DatumGetObjectId(values[Anum_pg_ts_parser_prstoken - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else if (strcmp(defel->defname, "end") == 0) { + Oid procoid; + values[Anum_pg_ts_parser_prsend - 1] = get_ts_parser_func(defel, Anum_pg_ts_parser_prsend); + procoid = DatumGetObjectId(values[Anum_pg_ts_parser_prsend - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else if (strcmp(defel->defname, "headline") == 0) { + Oid procoid; + values[Anum_pg_ts_parser_prsheadline - 1] = get_ts_parser_func(defel, Anum_pg_ts_parser_prsheadline); + procoid = DatumGetObjectId(values[Anum_pg_ts_parser_prsheadline - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else if (strcmp(defel->defname, "lextypes") == 0) { + Oid procoid; + values[Anum_pg_ts_parser_prslextype - 1] = get_ts_parser_func(defel, Anum_pg_ts_parser_prslextype); + procoid = DatumGetObjectId(values[Anum_pg_ts_parser_prslextype - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else ereport(ERROR, @@ -474,6 +495,10 @@ DefineTSDictionary(List *names, List *parameters) CatalogTupleInsert(dictRel, tup); + /* Lock dependent objects */ + LockNotPinnedObject(NamespaceRelationId, namespaceoid); + LockNotPinnedObject(TSTemplateRelationId, templId); + address = makeDictionaryDependencies(tup); /* Post creation hook for new text search dictionary */ @@ -723,6 +748,7 @@ DefineTSTemplate(List *names, List *parameters) namestrcpy(&dname, tmplname); values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname); values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid); + LockNotPinnedObject(NamespaceRelationId, namespaceoid); /* * loop over the definition list and extract the information we need. @@ -733,15 +759,23 @@ DefineTSTemplate(List *names, List *parameters) if (strcmp(defel->defname, "init") == 0) { + Oid procoid; + values[Anum_pg_ts_template_tmplinit - 1] = get_ts_template_func(defel, Anum_pg_ts_template_tmplinit); nulls[Anum_pg_ts_template_tmplinit - 1] = false; + procoid = DatumGetObjectId(values[Anum_pg_ts_template_tmplinit - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else if (strcmp(defel->defname, "lexize") == 0) { + Oid procoid; + values[Anum_pg_ts_template_tmpllexize - 1] = get_ts_template_func(defel, Anum_pg_ts_template_tmpllexize); nulls[Anum_pg_ts_template_tmpllexize - 1] = false; + procoid = DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1]); + LockNotPinnedObject(ProcedureRelationId, procoid); } else ereport(ERROR, @@ -998,6 +1032,10 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied) values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId()); values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid); + /* Lock dependent objects */ + LockNotPinnedObject(NamespaceRelationId, namespaceoid); + LockNotPinnedObject(TSParserRelationId, prsOid); + tup = heap_form_tuple(cfgRel->rd_att, values, nulls); CatalogTupleInsert(cfgRel, tup); @@ -1063,6 +1101,7 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied) slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno; slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict; + LockNotPinnedObject(TSDictionaryRelationId, cfgmap->mapdict); ExecStoreVirtualTuple(slot[slot_stored_count]); slot_stored_count++; @@ -1156,9 +1195,13 @@ ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt) { HeapTuple tup; + Form_pg_ts_config cfg; Oid cfgId; Relation relMap; ObjectAddress address; + ScanKeyData skey; + SysScanDesc scan; + HeapTuple maptup; /* Find the configuration */ tup = GetTSConfigTuple(stmt->cfgname); @@ -1168,7 +1211,8 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) errmsg("text search configuration \"%s\" does not exist", NameListToString(stmt->cfgname)))); - cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid; + cfg = (Form_pg_ts_config) GETSTRUCT(tup); + cfgId = cfg->oid; /* must be owner */ if (!object_ownercheck(TSConfigRelationId, cfgId, GetUserId())) @@ -1183,6 +1227,28 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) else if (stmt->tokentype) DropConfigurationMapping(stmt, tup, relMap); + /* Lock dependent objects */ + + ScanKeyInit(&skey, + Anum_pg_ts_config_map_mapcfg, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(cfgId)); + + scan = systable_beginscan(relMap, TSConfigMapIndexId, true, + NULL, 1, &skey); + + while (HeapTupleIsValid((maptup = systable_getnext(scan)))) + { + Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup); + + LockNotPinnedObject(TSDictionaryRelationId, cfgmap->mapdict); + } + + systable_endscan(scan); + + LockNotPinnedObject(NamespaceRelationId, cfg->cfgnamespace); + LockNotPinnedObject(TSParserRelationId, cfg->cfgparser); + /* Update dependencies */ makeConfigurationDependencies(tup, true, relMap); @@ -1414,6 +1480,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, repl_val[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictNew); repl_repl[Anum_pg_ts_config_map_mapdict - 1] = true; + LockNotPinnedObject(TSDictionaryRelationId, dictNew); + newtup = heap_modify_tuple(maptup, RelationGetDescr(relMap), repl_val, repl_null, repl_repl); @@ -1456,6 +1524,9 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1); slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]); + /* Lock dependent objects */ + LockNotPinnedObject(TSDictionaryRelationId, dictIds[j]); + ExecStoreVirtualTuple(slot[slotCount]); slotCount++; diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 2a6550de90..25be046308 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -1794,6 +1794,7 @@ makeRangeConstructors(const char *name, Oid namespace, * that they go away silently when the type is dropped. Note that * pg_dump depends on this choice to avoid dumping the constructors. */ + LockNotPinnedObject(TypeRelationId, rangeOid); recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); } } @@ -1859,6 +1860,7 @@ makeMultirangeConstructors(const char *name, Oid namespace, * that they go away silently when the type is dropped. Note that pg_dump * depends on this choice to avoid dumping the constructors. */ + LockNotPinnedObject(TypeRelationId, multirangeOid); recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); pfree(argtypes); @@ -2672,6 +2674,45 @@ AlterDomainDefault(List *names, Node *defaultRaw) CatalogTupleUpdate(rel, &tup->t_self, newtuple); + /* Lock dependent objects */ + typTup = (Form_pg_type) GETSTRUCT(newtuple); + + if (OidIsValid(typTup->typnamespace)) + LockNotPinnedObject(NamespaceRelationId, typTup->typnamespace); + + if (OidIsValid(typTup->typinput)) + LockNotPinnedObject(ProcedureRelationId, typTup->typinput); + + if (OidIsValid(typTup->typoutput)) + LockNotPinnedObject(ProcedureRelationId, typTup->typoutput); + + if (OidIsValid(typTup->typreceive)) + LockNotPinnedObject(ProcedureRelationId, typTup->typreceive); + + if (OidIsValid(typTup->typsend)) + LockNotPinnedObject(ProcedureRelationId, typTup->typsend); + + if (OidIsValid(typTup->typmodin)) + LockNotPinnedObject(ProcedureRelationId, typTup->typmodin); + + if (OidIsValid(typTup->typmodout)) + LockNotPinnedObject(ProcedureRelationId, typTup->typmodout); + + if (OidIsValid(typTup->typanalyze)) + LockNotPinnedObject(ProcedureRelationId, typTup->typanalyze); + + if (OidIsValid(typTup->typsubscript)) + LockNotPinnedObject(ProcedureRelationId, typTup->typsubscript); + + if (OidIsValid(typTup->typbasetype)) + LockNotPinnedObject(TypeRelationId, typTup->typbasetype); + + if (OidIsValid(typTup->typcollation)) + LockNotPinnedObject(CollationRelationId, typTup->typcollation); + + if (OidIsValid(typTup->typelem)) + LockNotPinnedObject(TypeRelationId, typTup->typelem); + /* Rebuild dependencies */ GenerateTypeDependencies(newtuple, rel, @@ -4278,10 +4319,13 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, if (oldNspOid != nspOid && (isCompositeType || typform->typtype != TYPTYPE_COMPOSITE) && !isImplicitArray) + { + LockNotPinnedObject(NamespaceRelationId, nspOid); if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "could not change schema dependency for type \"%s\"", format_type_be(typeOid)); + } InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); @@ -4573,6 +4617,7 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray, SysScanDesc scan; ScanKeyData key[1]; HeapTuple domainTup; + Form_pg_type typeForm; /* Since this function recurses, it could be driven to stack overflow */ check_stack_depth(); @@ -4621,6 +4666,45 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray, newtup = heap_modify_tuple(tup, RelationGetDescr(catalog), values, nulls, replaces); + /* Lock dependent objects */ + typeForm = (Form_pg_type) GETSTRUCT(newtup); + + if (OidIsValid(typeForm->typnamespace)) + LockNotPinnedObject(NamespaceRelationId, typeForm->typnamespace); + + if (OidIsValid(typeForm->typinput)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typinput); + + if (OidIsValid(typeForm->typoutput)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typoutput); + + if (OidIsValid(typeForm->typreceive)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typreceive); + + if (OidIsValid(typeForm->typsend)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typsend); + + if (OidIsValid(typeForm->typmodin)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typmodin); + + if (OidIsValid(typeForm->typmodout)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typmodout); + + if (OidIsValid(typeForm->typanalyze)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typanalyze); + + if (OidIsValid(typeForm->typsubscript)) + LockNotPinnedObject(ProcedureRelationId, typeForm->typsubscript); + + if (OidIsValid(typeForm->typbasetype)) + LockNotPinnedObject(TypeRelationId, typeForm->typbasetype); + + if (OidIsValid(typeForm->typcollation)) + LockNotPinnedObject(CollationRelationId, typeForm->typcollation); + + if (OidIsValid(typeForm->typelem)) + LockNotPinnedObject(TypeRelationId, typeForm->typelem); + CatalogTupleUpdate(catalog, &newtup->t_self, newtup); /* Rebuild dependencies for this type */ diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 6cc9a8d8bf..c930eca262 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -155,6 +155,7 @@ InsertRule(const char *rulname, referenced.objectId = eventrel_oid; referenced.objectSubId = 0; + LockNotPinnedObject(RelationRelationId, eventrel_oid); recordDependencyOn(&myself, &referenced, (evtype == CMD_SELECT) ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO); diff --git a/src/backend/utils/errcodes.txt b/src/backend/utils/errcodes.txt index 97d91eb1e9..33b0c750e4 100644 --- a/src/backend/utils/errcodes.txt +++ b/src/backend/utils/errcodes.txt @@ -277,6 +277,7 @@ Section: Class 28 - Invalid Authorization Specification Section: Class 2B - Dependent Privilege Descriptors Still Exist 2B000 E ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST dependent_privilege_descriptors_still_exist +2BP02 E ERRCODE_DEPENDENT_OBJECTS_DOES_NOT_EXIST dependent_objects_does_not_exist 2BP01 E ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST dependent_objects_still_exist Section: Class 2D - Invalid Transaction Termination diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 6908ca7180..0546bcbe16 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -101,6 +101,8 @@ typedef struct ObjectAddresses ObjectAddresses; /* in dependency.c */ extern void AcquireDeletionLock(const ObjectAddress *object, int flags); +extern void LockNotPinnedObjectById(const ObjectAddress *object); +extern void LockNotPinnedObject(Oid classid, Oid objid); extern void ReleaseDeletionLock(const ObjectAddress *object); @@ -172,6 +174,7 @@ extern long changeDependenciesOf(Oid classId, Oid oldObjectId, extern long changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId); +extern bool isObjectPinned(const ObjectAddress *object); extern Oid getExtensionOfObject(Oid classId, Oid objectId); extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId); diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h index 3a70d80e32..56f746264b 100644 --- a/src/include/catalog/objectaddress.h +++ b/src/include/catalog/objectaddress.h @@ -53,6 +53,7 @@ extern void check_object_ownership(Oid roleid, Node *object, Relation relation); extern Oid get_object_namespace(const ObjectAddress *address); +extern bool ObjectByIdExist(const ObjectAddress *address); extern bool is_objectclass_supported(Oid class_id); extern const char *get_object_class_descr(Oid class_id); diff --git a/src/test/isolation/expected/test_dependencies_locks.out b/src/test/isolation/expected/test_dependencies_locks.out new file mode 100644 index 0000000000..9b645d7aa5 --- /dev/null +++ b/src/test/isolation/expected/test_dependencies_locks.out @@ -0,0 +1,129 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_begin s1_create_function_in_schema s2_drop_schema s1_commit +step s1_begin: BEGIN; +step s1_create_function_in_schema: CREATE FUNCTION testschema.foo() RETURNS int AS 'select 1' LANGUAGE sql; +step s2_drop_schema: DROP SCHEMA testschema; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_schema: <... completed> +ERROR: cannot drop schema testschema because other objects depend on it + +starting permutation: s2_begin s2_drop_schema s1_create_function_in_schema s2_commit +step s2_begin: BEGIN; +step s2_drop_schema: DROP SCHEMA testschema; +step s1_create_function_in_schema: CREATE FUNCTION testschema.foo() RETURNS int AS 'select 1' LANGUAGE sql; <waiting ...> +step s2_commit: COMMIT; +step s1_create_function_in_schema: <... completed> +ERROR: schema testschema does not exist + +starting permutation: s1_begin s1_alter_function_schema s2_drop_alterschema s1_commit +step s1_begin: BEGIN; +step s1_alter_function_schema: ALTER FUNCTION public.falter() SET SCHEMA alterschema; +step s2_drop_alterschema: DROP SCHEMA alterschema; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_alterschema: <... completed> +ERROR: cannot drop schema alterschema because other objects depend on it + +starting permutation: s2_begin s2_drop_alterschema s1_alter_function_schema s2_commit +step s2_begin: BEGIN; +step s2_drop_alterschema: DROP SCHEMA alterschema; +step s1_alter_function_schema: ALTER FUNCTION public.falter() SET SCHEMA alterschema; <waiting ...> +step s2_commit: COMMIT; +step s1_alter_function_schema: <... completed> +ERROR: schema alterschema does not exist + +starting permutation: s1_begin s1_create_function_with_argtype s2_drop_foo_type s1_commit +step s1_begin: BEGIN; +step s1_create_function_with_argtype: CREATE FUNCTION fooargtype(num foo) RETURNS int AS 'select 1' LANGUAGE sql; +step s2_drop_foo_type: DROP TYPE public.foo; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_foo_type: <... completed> +ERROR: cannot drop type foo because other objects depend on it + +starting permutation: s2_begin s2_drop_foo_type s1_create_function_with_argtype s2_commit +step s2_begin: BEGIN; +step s2_drop_foo_type: DROP TYPE public.foo; +step s1_create_function_with_argtype: CREATE FUNCTION fooargtype(num foo) RETURNS int AS 'select 1' LANGUAGE sql; <waiting ...> +step s2_commit: COMMIT; +step s1_create_function_with_argtype: <... completed> +ERROR: type foo does not exist + +starting permutation: s1_begin s1_create_function_with_rettype s2_drop_foo_rettype s1_commit +step s1_begin: BEGIN; +step s1_create_function_with_rettype: CREATE FUNCTION footrettype() RETURNS id LANGUAGE sql RETURN 1; +step s2_drop_foo_rettype: DROP DOMAIN id; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_foo_rettype: <... completed> +ERROR: cannot drop type id because other objects depend on it + +starting permutation: s2_begin s2_drop_foo_rettype s1_create_function_with_rettype s2_commit +step s2_begin: BEGIN; +step s2_drop_foo_rettype: DROP DOMAIN id; +step s1_create_function_with_rettype: CREATE FUNCTION footrettype() RETURNS id LANGUAGE sql RETURN 1; <waiting ...> +step s2_commit: COMMIT; +step s1_create_function_with_rettype: <... completed> +ERROR: type id does not exist + +starting permutation: s1_begin s1_create_function_with_function s2_drop_function_f s1_commit +step s1_begin: BEGIN; +step s1_create_function_with_function: CREATE FUNCTION foofunc() RETURNS int LANGUAGE SQL RETURN f() + 1; +step s2_drop_function_f: DROP FUNCTION f(); <waiting ...> +step s1_commit: COMMIT; +step s2_drop_function_f: <... completed> +ERROR: cannot drop function f() because other objects depend on it + +starting permutation: s2_begin s2_drop_function_f s1_create_function_with_function s2_commit +step s2_begin: BEGIN; +step s2_drop_function_f: DROP FUNCTION f(); +step s1_create_function_with_function: CREATE FUNCTION foofunc() RETURNS int LANGUAGE SQL RETURN f() + 1; <waiting ...> +step s2_commit: COMMIT; +step s1_create_function_with_function: <... completed> +ERROR: function f() does not exist + +starting permutation: s1_begin s1_create_domain_with_domain s2_drop_domain_id s1_commit +step s1_begin: BEGIN; +step s1_create_domain_with_domain: CREATE DOMAIN idid as id; +step s2_drop_domain_id: DROP DOMAIN id; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_domain_id: <... completed> +ERROR: cannot drop type id because other objects depend on it + +starting permutation: s2_begin s2_drop_domain_id s1_create_domain_with_domain s2_commit +step s2_begin: BEGIN; +step s2_drop_domain_id: DROP DOMAIN id; +step s1_create_domain_with_domain: CREATE DOMAIN idid as id; <waiting ...> +step s2_commit: COMMIT; +step s1_create_domain_with_domain: <... completed> +ERROR: type id does not exist + +starting permutation: s1_begin s1_create_table_with_type s2_drop_footab_type s1_commit +step s1_begin: BEGIN; +step s1_create_table_with_type: CREATE TABLE tabtype(a footab); +step s2_drop_footab_type: DROP TYPE public.footab; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_footab_type: <... completed> +ERROR: cannot drop type footab because other objects depend on it + +starting permutation: s2_begin s2_drop_footab_type s1_create_table_with_type s2_commit +step s2_begin: BEGIN; +step s2_drop_footab_type: DROP TYPE public.footab; +step s1_create_table_with_type: CREATE TABLE tabtype(a footab); <waiting ...> +step s2_commit: COMMIT; +step s1_create_table_with_type: <... completed> +ERROR: type footab does not exist + +starting permutation: s1_begin s1_create_server_with_fdw_wrapper s2_drop_fdw_wrapper s1_commit +step s1_begin: BEGIN; +step s1_create_server_with_fdw_wrapper: CREATE SERVER srv_fdw_wrapper FOREIGN DATA WRAPPER fdw_wrapper; +step s2_drop_fdw_wrapper: DROP FOREIGN DATA WRAPPER fdw_wrapper RESTRICT; <waiting ...> +step s1_commit: COMMIT; +step s2_drop_fdw_wrapper: <... completed> +ERROR: cannot drop foreign-data wrapper fdw_wrapper because other objects depend on it + +starting permutation: s2_begin s2_drop_fdw_wrapper s1_create_server_with_fdw_wrapper s2_commit +step s2_begin: BEGIN; +step s2_drop_fdw_wrapper: DROP FOREIGN DATA WRAPPER fdw_wrapper RESTRICT; +step s1_create_server_with_fdw_wrapper: CREATE SERVER srv_fdw_wrapper FOREIGN DATA WRAPPER fdw_wrapper; <waiting ...> +step s2_commit: COMMIT; +step s1_create_server_with_fdw_wrapper: <... completed> +ERROR: foreign-data wrapper fdw_wrapper does not exist diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 143109aa4d..0e80dfecfb 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -115,3 +115,4 @@ test: serializable-parallel-2 test: serializable-parallel-3 test: matview-write-skew test: lock-nowait +test: test_dependencies_locks diff --git a/src/test/isolation/specs/test_dependencies_locks.spec b/src/test/isolation/specs/test_dependencies_locks.spec new file mode 100644 index 0000000000..5d04dfe9dc --- /dev/null +++ b/src/test/isolation/specs/test_dependencies_locks.spec @@ -0,0 +1,89 @@ +setup +{ + CREATE SCHEMA testschema; + CREATE SCHEMA alterschema; + CREATE TYPE public.foo as enum ('one', 'two'); + CREATE TYPE public.footab as enum ('three', 'four'); + CREATE DOMAIN id AS int; + CREATE FUNCTION f() RETURNS int LANGUAGE SQL RETURN 1; + CREATE FUNCTION public.falter() RETURNS int LANGUAGE SQL RETURN 1; + CREATE FOREIGN DATA WRAPPER fdw_wrapper; +} + +teardown +{ + DROP FUNCTION IF EXISTS testschema.foo(); + DROP FUNCTION IF EXISTS fooargtype(num foo); + DROP FUNCTION IF EXISTS footrettype(); + DROP FUNCTION IF EXISTS foofunc(); + DROP FUNCTION IF EXISTS public.falter(); + DROP FUNCTION IF EXISTS alterschema.falter(); + DROP DOMAIN IF EXISTS idid; + DROP SERVER IF EXISTS srv_fdw_wrapper; + DROP TABLE IF EXISTS tabtype; + DROP SCHEMA IF EXISTS testschema; + DROP SCHEMA IF EXISTS alterschema; + DROP TYPE IF EXISTS public.foo; + DROP TYPE IF EXISTS public.footab; + DROP DOMAIN IF EXISTS id; + DROP FUNCTION IF EXISTS f(); + DROP FOREIGN DATA WRAPPER IF EXISTS fdw_wrapper; +} + +session "s1" + +step "s1_begin" { BEGIN; } +step "s1_create_function_in_schema" { CREATE FUNCTION testschema.foo() RETURNS int AS 'select 1' LANGUAGE sql; } +step "s1_create_function_with_argtype" { CREATE FUNCTION fooargtype(num foo) RETURNS int AS 'select 1' LANGUAGE sql; } +step "s1_create_function_with_rettype" { CREATE FUNCTION footrettype() RETURNS id LANGUAGE sql RETURN 1; } +step "s1_create_function_with_function" { CREATE FUNCTION foofunc() RETURNS int LANGUAGE SQL RETURN f() + 1; } +step "s1_alter_function_schema" { ALTER FUNCTION public.falter() SET SCHEMA alterschema; } +step "s1_create_domain_with_domain" { CREATE DOMAIN idid as id; } +step "s1_create_table_with_type" { CREATE TABLE tabtype(a footab); } +step "s1_create_server_with_fdw_wrapper" { CREATE SERVER srv_fdw_wrapper FOREIGN DATA WRAPPER fdw_wrapper; } +step "s1_commit" { COMMIT; } + +session "s2" + +step "s2_begin" { BEGIN; } +step "s2_drop_schema" { DROP SCHEMA testschema; } +step "s2_drop_alterschema" { DROP SCHEMA alterschema; } +step "s2_drop_foo_type" { DROP TYPE public.foo; } +step "s2_drop_foo_rettype" { DROP DOMAIN id; } +step "s2_drop_footab_type" { DROP TYPE public.footab; } +step "s2_drop_function_f" { DROP FUNCTION f(); } +step "s2_drop_domain_id" { DROP DOMAIN id; } +step "s2_drop_fdw_wrapper" { DROP FOREIGN DATA WRAPPER fdw_wrapper RESTRICT; } +step "s2_commit" { COMMIT; } + +# function - schema +permutation "s1_begin" "s1_create_function_in_schema" "s2_drop_schema" "s1_commit" +permutation "s2_begin" "s2_drop_schema" "s1_create_function_in_schema" "s2_commit" + +# alter function - schema +permutation "s1_begin" "s1_alter_function_schema" "s2_drop_alterschema" "s1_commit" +permutation "s2_begin" "s2_drop_alterschema" "s1_alter_function_schema" "s2_commit" + +# function - argtype +permutation "s1_begin" "s1_create_function_with_argtype" "s2_drop_foo_type" "s1_commit" +permutation "s2_begin" "s2_drop_foo_type" "s1_create_function_with_argtype" "s2_commit" + +# function - rettype +permutation "s1_begin" "s1_create_function_with_rettype" "s2_drop_foo_rettype" "s1_commit" +permutation "s2_begin" "s2_drop_foo_rettype" "s1_create_function_with_rettype" "s2_commit" + +# function - function +permutation "s1_begin" "s1_create_function_with_function" "s2_drop_function_f" "s1_commit" +permutation "s2_begin" "s2_drop_function_f" "s1_create_function_with_function" "s2_commit" + +# domain - domain +permutation "s1_begin" "s1_create_domain_with_domain" "s2_drop_domain_id" "s1_commit" +permutation "s2_begin" "s2_drop_domain_id" "s1_create_domain_with_domain" "s2_commit" + +# table - type +permutation "s1_begin" "s1_create_table_with_type" "s2_drop_footab_type" "s1_commit" +permutation "s2_begin" "s2_drop_footab_type" "s1_create_table_with_type" "s2_commit" + +# server - foreign data wrapper +permutation "s1_begin" "s1_create_server_with_fdw_wrapper" "s2_drop_fdw_wrapper" "s1_commit" +permutation "s2_begin" "s2_drop_fdw_wrapper" "s1_create_server_with_fdw_wrapper" "s2_commit" diff --git a/src/test/modules/test_oat_hooks/expected/alter_table.out b/src/test/modules/test_oat_hooks/expected/alter_table.out index 8cbacca2c9..df8d276dfc 100644 --- a/src/test/modules/test_oat_hooks/expected/alter_table.out +++ b/src/test/modules/test_oat_hooks/expected/alter_table.out @@ -37,6 +37,8 @@ NOTICE: in object access: superuser attempting create (subId=0x0) [internal] NOTICE: in object access: superuser finished create (subId=0x0) [internal] NOTICE: in object access: superuser attempting create (subId=0x0) [internal] NOTICE: in object access: superuser finished create (subId=0x0) [internal] +NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed] +NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed] NOTICE: in process utility: superuser finished CREATE TABLE CREATE RULE test_oat_notify AS ON UPDATE TO test_oat_schema.test_oat_tab @@ -62,8 +64,6 @@ BEGIN END IF; END; $$; NOTICE: in process utility: superuser attempting CREATE FUNCTION -NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed] -NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed] NOTICE: in object access: superuser attempting create (subId=0x0) [explicit] NOTICE: in object access: superuser finished create (subId=0x0) [explicit] NOTICE: in process utility: superuser finished CREATE FUNCTION diff --git a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out index effdc49145..da6d931994 100644 --- a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out +++ b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out @@ -86,6 +86,8 @@ NOTICE: in object access: superuser attempting create (subId=0x0) [internal] NOTICE: in object access: superuser finished create (subId=0x0) [internal] NOTICE: in object access: superuser attempting create (subId=0x0) [internal] NOTICE: in object access: superuser finished create (subId=0x0) [internal] +NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed] +NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed] NOTICE: in process utility: superuser finished CREATE TABLE CREATE INDEX regress_test_table_t_idx ON regress_test_table (t); NOTICE: in process utility: superuser attempting CREATE INDEX diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 143ae7c09c..a34e238024 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2866,11 +2866,12 @@ begin; alter table alterlock2 add constraint alterlock2nv foreign key (f1) references alterlock (f1) NOT VALID; select * from my_locks order by 1; - relname | max_lockmode -------------+----------------------- - alterlock | ShareRowExclusiveLock - alterlock2 | ShareRowExclusiveLock -(2 rows) + relname | max_lockmode +----------------+----------------------- + alterlock | ShareRowExclusiveLock + alterlock2 | ShareRowExclusiveLock + alterlock_pkey | AccessShareLock +(3 rows) commit; begin; -- 2.34.1 --+nHX6Y4wAeAx6W3F-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v4 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9a199dd9bfb..3b80d331815 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..2b44afdbf25 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2020,13 +2020,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2341,11 +2334,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..18d49a6fc17 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = n.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --g1KZ71ry6DNksXN0-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v3 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++------- src/backend/access/common/reloptions.c | 49 +++++------- src/backend/catalog/toasting.c | 31 ++++---- src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +--- src/backend/commands/tablecmds.c | 19 +---- src/backend/commands/vacuum.c | 14 +--- src/backend/postmaster/autovacuum.c | 48 +++++------- src/backend/tcop/utility.c | 19 +---- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++ src/include/access/reloptions.h | 24 +++--- src/include/catalog/toasting.h | 6 +- .../injection_points/expected/vacuum.out | 24 +++--- .../modules/injection_points/sql/vacuum.sql | 20 ++--- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++------------ src/test/regress/expected/vacuum.out | 8 -- src/test/regress/sql/alter_table.sql | 4 - src/test/regress/sql/reloptions.sql | 32 +------- src/test/regress/sql/vacuum.sql | 8 -- 20 files changed, 199 insertions(+), 326 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/modules/injection_points/expected/vacuum.out b/src/test/modules/injection_points/expected/vacuum.out index 58df59fa927..dcfa729d05e 100644 --- a/src/test/modules/injection_points/expected/vacuum.out +++ b/src/test/modules/injection_points/expected/vacuum.out @@ -43,29 +43,29 @@ SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); (1 row) -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; +NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled +NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled NOTICE: notice triggered for injection point vacuum-truncate-enabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled NOTICE: notice triggered for injection point vacuum-index-cleanup-disabled NOTICE: notice triggered for injection point vacuum-truncate-disabled -NOTICE: notice triggered for injection point vacuum-index-cleanup-enabled -NOTICE: notice triggered for injection point vacuum-truncate-enabled -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; NOTICE: notice triggered for injection point vacuum-index-cleanup-auto @@ -80,8 +80,8 @@ NOTICE: notice triggered for injection point vacuum-index-cleanup-auto NOTICE: notice triggered for injection point vacuum-truncate-enabled RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); injection_points_detach diff --git a/src/test/modules/injection_points/sql/vacuum.sql b/src/test/modules/injection_points/sql/vacuum.sql index 23760dd0f38..ee7a2e0566e 100644 --- a/src/test/modules/injection_points/sql/vacuum.sql +++ b/src/test/modules/injection_points/sql/vacuum.sql @@ -11,22 +11,22 @@ SELECT injection_points_attach('vacuum-truncate-disabled', 'notice'); SELECT injection_points_attach('vacuum-truncate-enabled', 'notice'); -- Check state of index_cleanup and truncate in VACUUM. -CREATE TABLE vac_tab_on_toast_off(i int, j text) WITH +CREATE TABLE vac_tab_on_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false, - vacuum_truncate=true, toast.vacuum_truncate=false); -CREATE TABLE vac_tab_off_toast_on(i int, j text) WITH + vacuum_index_cleanup=true, + vacuum_truncate=true); +CREATE TABLE vac_tab_off_toast(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=false, toast.vacuum_index_cleanup=true, - vacuum_truncate=false, toast.vacuum_truncate=true); + vacuum_index_cleanup=false, + vacuum_truncate=false); -- Multiple relations should use their options in isolation. -VACUUM vac_tab_on_toast_off, vac_tab_off_toast_on; +VACUUM vac_tab_on_toast, vac_tab_off_toast; -- Check "auto" case of index_cleanup and "truncate" controlled by -- its GUC. CREATE TABLE vac_tab_auto(i int, j text) WITH (autovacuum_enabled=false, - vacuum_index_cleanup=auto, toast.vacuum_index_cleanup=auto); + vacuum_index_cleanup=auto); SET vacuum_truncate = false; VACUUM vac_tab_auto; SET vacuum_truncate = true; @@ -34,8 +34,8 @@ VACUUM vac_tab_auto; RESET vacuum_truncate; DROP TABLE vac_tab_auto; -DROP TABLE vac_tab_on_toast_off; -DROP TABLE vac_tab_off_toast_on; +DROP TABLE vac_tab_on_toast; +DROP TABLE vac_tab_off_toast; -- Cleanup SELECT injection_points_detach('vacuum-index-cleanup-auto'); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --UOGHeidpVrTAfMhN-- ^ permalink raw reply [nested|flat] 132+ messages in thread
* [PATCH v2 1/1] remove toast reloptions @ 2026-04-07 20:30 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 132+ messages in thread From: Nathan Bossart @ 2026-04-07 20:30 UTC (permalink / raw) --- doc/src/sgml/ref/create_table.sgml | 51 ++++++++------- src/backend/access/common/reloptions.c | 49 ++++++--------- src/backend/catalog/toasting.c | 31 ++++------ src/backend/commands/createas.c | 13 +--- src/backend/commands/repack.c | 15 +---- src/backend/commands/tablecmds.c | 19 ++---- src/backend/commands/vacuum.c | 14 +---- src/backend/postmaster/autovacuum.c | 48 +++++---------- src/backend/tcop/utility.c | 19 +----- src/bin/pg_upgrade/check.c | 75 +++++++++++++++++++++++ src/include/access/reloptions.h | 24 +++----- src/include/catalog/toasting.h | 6 +- src/test/regress/expected/alter_table.out | 9 --- src/test/regress/expected/reloptions.out | 56 ++--------------- src/test/regress/expected/vacuum.out | 8 --- src/test/regress/sql/alter_table.sql | 4 -- src/test/regress/sql/reloptions.sql | 32 +--------- src/test/regress/sql/vacuum.sql | 8 --- 18 files changed, 177 insertions(+), 304 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e342585c7f0..b8d2a657d10 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1589,14 +1589,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Storage parameters for indexes are documented in <xref linkend="sql-createindex"/>. The storage parameters currently - available for tables are listed below. For many of these parameters, as - shown, there is an additional parameter with the same name prefixed with - <literal>toast.</literal>, which controls the behavior of the + available for tables are listed below. Unless otherwise noted, a table's + parameter value also controls the behavior of the table's secondary <acronym>TOAST</acronym> table, if any (see <xref linkend="storage-toast"/> for more information about TOAST). - If a table parameter value is set and the - equivalent <literal>toast.</literal> parameter is not, the TOAST table - will use the table's parameter value. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions. </para> @@ -1622,7 +1618,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM updates</link> more likely. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are - appropriate. This parameter cannot be set for TOAST tables. + appropriate. This parameter does not affect the table's secondary TOAST + table. </para> </listitem> </varlistentry> @@ -1648,7 +1645,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> @@ -1671,7 +1668,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled"> - <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>) + <term><literal>autovacuum_enabled</literal> (<type>boolean</type>) <indexterm> <primary><varname>autovacuum_enabled</varname> storage parameter</primary> </indexterm> @@ -1696,7 +1693,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup"> - <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>) + <term><literal>vacuum_index_cleanup</literal> (<type>enum</type>) <indexterm> <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary> </indexterm> @@ -1722,7 +1719,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate"> - <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>) + <term><literal>vacuum_truncate</literal> (<type>boolean</type>) <indexterm> <primary><varname>vacuum_truncate</varname></primary> <secondary>storage parameter</secondary> @@ -1755,7 +1752,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold"> - <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1770,7 +1767,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-max-threshold" xreflabel="autovacuum_vacuum_max_threshold"> - <term><literal>autovacuum_vacuum_max_threshold</literal>, <literal>toast.autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_max_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_max_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1785,7 +1782,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor"> - <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1800,7 +1797,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold"> - <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary> <secondary>storage parameter</secondary> @@ -1815,7 +1812,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor"> - <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary> <secondary>storage parameter</secondary> @@ -1860,7 +1857,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay"> - <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) + <term><literal>autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_delay</varname></primary> <secondary>storage parameter</secondary> @@ -1875,7 +1872,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit"> - <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) + <term><literal>autovacuum_vacuum_cost_limit</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_vacuum_cost_limit</varname></primary> <secondary>storage parameter</secondary> @@ -1890,7 +1887,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age"> - <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1907,7 +1904,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age"> - <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1924,7 +1921,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age"> - <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1938,7 +1935,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age"> - <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary> </indexterm> @@ -1956,7 +1953,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age"> - <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary> <secondary>storage parameter</secondary> @@ -1975,7 +1972,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age"> - <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) + <term><literal>autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>) <indexterm> <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary> </indexterm> @@ -1989,7 +1986,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration"> - <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>) + <term><literal>log_autovacuum_min_duration</literal> (<type>integer</type>) <indexterm> <primary><varname>log_autovacuum_min_duration</varname></primary> <secondary>storage parameter</secondary> @@ -2019,7 +2016,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM </varlistentry> <varlistentry id="reloption-vacuum-max-eager-freeze-failure-rate" xreflabel="vacuum_max_eager_freeze_failure_rate"> - <term><literal>vacuum_max_eager_freeze_failure_rate</literal>, <literal>toast.vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) + <term><literal>vacuum_max_eager_freeze_failure_rate</literal> (<type>floating point</type>) <indexterm> <primary><varname>vacuum_max_eager_freeze_failure_rate</varname></primary> <secondary>storage parameter</secondary> @@ -2044,7 +2041,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM Declare the table as an additional catalog table for purposes of logical replication. See <xref linkend="logicaldecoding-capabilities"/> for details. - This parameter cannot be set for TOAST tables. + This parameter does not affect the table's secondary TOAST table. </para> </listitem> </varlistentry> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3e832c3797e..50d9805f3d8 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, true @@ -172,7 +172,7 @@ static relopt_ternary ternaryRelOpts[] = { "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock } }, @@ -249,7 +249,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -258,7 +258,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -267,7 +267,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -2, -1, INT_MAX @@ -285,7 +285,7 @@ static relopt_int intRelOpts[] = { "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 1, 10000 @@ -294,7 +294,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -303,7 +303,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 1000000000 @@ -312,7 +312,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 100000, 2000000000 @@ -321,7 +321,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 10000, 2000000000 @@ -330,7 +330,7 @@ static relopt_int intRelOpts[] = { "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -338,7 +338,7 @@ static relopt_int intRelOpts[] = { "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0, 2000000000 }, @@ -346,7 +346,7 @@ static relopt_int intRelOpts[] = { "log_autovacuum_min_duration", "Sets the minimum execution time above which vacuum actions by autovacuum will be logged", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, -1, INT_MAX @@ -424,7 +424,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -433,7 +433,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -442,7 +442,7 @@ static relopt_real realRelOpts[] = { "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -460,7 +460,7 @@ static relopt_real realRelOpts[] = { "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, -1, 0.0, 1.0 @@ -554,7 +554,7 @@ static relopt_enum enumRelOpts[] = { "vacuum_index_cleanup", "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP, ShareUpdateExclusiveLock }, StdRdOptIndexCleanupValues, @@ -2163,21 +2163,8 @@ view_reloptions(Datum reloptions, bool validate) bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) { - StdRdOptions *rdopts; - switch (relkind) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; case RELKIND_RELATION: case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd25..9f1f822702c 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -34,11 +34,11 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, +static void CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast); static bool needs_toast_table(Relation rel); @@ -48,35 +48,30 @@ static bool needs_toast_table(Relation rel); * If the table needs a toast table, and doesn't already have one, * then create a toast table for it. * - * reloptions for the toast table can be passed, too. Pass (Datum) 0 - * for default reloptions. - * * We expect the caller to have verified that the relation is a table and have * already done any necessary permission checks. Callers expect this function * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode) +AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, true, InvalidOid); + CheckAndCreateToastTable(relOid, lockmode, true, InvalidOid); } void -NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, - Oid OIDOldToast) +NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast) { - CheckAndCreateToastTable(relOid, reloptions, lockmode, false, OIDOldToast); + CheckAndCreateToastTable(relOid, lockmode, false, OIDOldToast); } void -NewRelationCreateToastTable(Oid relOid, Datum reloptions) +NewRelationCreateToastTable(Oid relOid) { - CheckAndCreateToastTable(relOid, reloptions, AccessExclusiveLock, false, - InvalidOid); + CheckAndCreateToastTable(relOid, AccessExclusiveLock, false, InvalidOid); } static void -CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, +CheckAndCreateToastTable(Oid relOid, LOCKMODE lockmode, bool check, Oid OIDOldToast) { Relation rel; @@ -84,7 +79,7 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, + (void) create_toast_table(rel, InvalidOid, InvalidOid, lockmode, check, OIDOldToast); table_close(rel, NoLock); @@ -108,7 +103,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0, + if (!create_toast_table(rel, toastOid, toastIndexOid, AccessExclusiveLock, false, InvalidOid)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -126,7 +121,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) */ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check, + LOCKMODE lockmode, bool check, Oid OIDOldToast) { Oid relOid = RelationGetRelid(rel); @@ -266,7 +261,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, shared_relation, mapped_relation, ONCOMMIT_NOOP, - reloptions, + (Datum) 0, false, true, true, diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6dbb831ca89..188e167999b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -84,8 +84,6 @@ create_ctas_internal(List *attrList, IntoClause *into) CreateStmt *create = makeNode(CreateStmt); bool is_matview; char relkind; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -120,16 +118,7 @@ create_ctas_internal(List *attrList, IntoClause *into) */ CommandCounterIncrement(); - /* parse and validate reloptions for the toast table */ - toast_options = transformRelOptions((Datum) 0, - create->options, - "toast", - validnsps, - true, false); - - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId); /* Create the "view" part of a materialized view. */ if (is_matview) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9d162957bc3..5064d8e2349 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -1201,20 +1201,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, */ toastid = OldHeap->rd_rel->reltoastrelid; if (OidIsValid(toastid)) - { - /* keep the existing toast table's reloptions, if any */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", toastid); - reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, - &isNull); - if (isNull) - reloptions = (Datum) 0; - - NewHeapCreateToastTable(OIDNewHeap, reloptions, lockmode, toastid); - - ReleaseSysCache(tuple); - } + NewHeapCreateToastTable(OIDNewHeap, lockmode, toastid); table_close(OldHeap, NoLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d8d7969bf30..a254509cbb5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -827,7 +827,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -976,7 +975,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, true, false); switch (relkind) @@ -5433,7 +5432,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, tab->relkind == RELKIND_PARTITIONED_TABLE) && tab->partition_constraint == NULL) || tab->relkind == RELKIND_MATVIEW) - AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode); + AlterTableCreateToastTable(tab->relid, lockmode); } } @@ -16927,7 +16926,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -16960,7 +16958,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } /* Generate new proposed reloptions (text array) */ - newOptions = transformRelOptions(datum, defList, NULL, validnsps, false, + newOptions = transformRelOptions(datum, defList, NULL, NULL, false, operation == AT_ResetRelOptions); /* Validate */ @@ -17083,20 +17081,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, datum = (Datum) 0; } - newOptions = transformRelOptions(datum, defList, "toast", validnsps, - false, operation == AT_ResetRelOptions); - - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); - memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - if (newOptions != (Datum) 0) - repl_val[Anum_pg_class_reloptions - 1] = newOptions; - else - repl_null[Anum_pg_class_reloptions - 1] = true; - + repl_null[Anum_pg_class_reloptions - 1] = true; repl_repl[Anum_pg_class_reloptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..ed670b3e3f1 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2015,13 +2015,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, Oid save_userid; int save_sec_context; int save_nestlevel; - VacuumParams toast_vacuum_params; - - /* - * This function scribbles on the parameters, so make a copy early to - * avoid affecting the TOAST table (if we do end up recursing to it). - */ - memcpy(&toast_vacuum_params, ¶ms, sizeof(VacuumParams)); /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -2336,11 +2329,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, * relation. NB: This is only safe to do because we hold a session * lock on the main relation that prevents concurrent deletion. */ - toast_vacuum_params.options |= VACOPT_PROCESS_MAIN; - toast_vacuum_params.toast_parent = relid; + params.options |= VACOPT_PROCESS_MAIN; + params.toast_parent = relid; - vacuum_rel(toast_relid, NULL, toast_vacuum_params, bstrategy, - isTopLevel); + vacuum_rel(toast_relid, NULL, params, bstrategy, isTopLevel); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index a5a8db2ff88..c0e7cbf2cb8 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2139,8 +2139,9 @@ do_autovacuum(void) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid; - AutoVacOpts *relopts; - bool free_relopts = false; + av_relation *hentry; + bool found; + AutoVacOpts *relopts = NULL; bool dovacuum; bool doanalyze; bool wraparound; @@ -2154,22 +2155,10 @@ do_autovacuum(void) relid = classForm->oid; - /* - * fetch reloptions -- if this toast table does not have them, try the - * main rel - */ - relopts = extract_autovac_opts(tuple, pg_class_desc); - if (relopts) - free_relopts = true; - else - { - av_relation *hentry; - bool found; - - hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); - if (found && hentry->ar_hasrelopts) - relopts = &hentry->ar_reloptions; - } + /* Use reloptions from main rel. */ + hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + relopts = &hentry->ar_reloptions; relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, @@ -2186,10 +2175,6 @@ do_autovacuum(void) table->score = scores.max; tables_to_process = lappend(tables_to_process, table); } - - /* Release stuff to avoid leakage */ - if (free_relopts) - pfree(relopts); } table_endscan(relScan); @@ -2826,7 +2811,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool doanalyze; autovac_table *tab = NULL; bool wraparound; - AutoVacOpts *avopts; + AutoVacOpts *avopts = NULL; bool free_avopts = false; AutoVacuumScores scores; @@ -2838,13 +2823,15 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, /* * Get the applicable reloptions. If it is a TOAST table, try to get the - * main table reloptions if the toast table itself doesn't have. + * main table reloptions. */ - avopts = extract_autovac_opts(classTup, pg_class_desc); - if (avopts) - free_avopts = true; - else if (classForm->relkind == RELKIND_TOASTVALUE && - table_toast_map != NULL) + if (classForm->relkind != RELKIND_TOASTVALUE) + { + avopts = extract_autovac_opts(classTup, pg_class_desc); + if (avopts) + free_avopts = true; + } + else if (table_toast_map) { av_relation *hentry; bool found; @@ -3127,8 +3114,7 @@ relation_needs_vacanalyze(Oid relid, /* * Determine vacuum/analyze equation parameters. We have two possible - * sources: the passed reloptions (which could be a main table or a toast - * table), or the autovacuum GUC variables. + * sources: the passed reloptions or the autovacuum GUC variables. */ /* -1 in autovac setting means use plain vacuum_scale_factor */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..d089e02c216 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1159,8 +1159,6 @@ ProcessUtilitySlow(ParseState *pstate, if (IsA(stmt, CreateStmt)) { CreateStmt *cstmt = (CreateStmt *) stmt; - Datum toast_options; - const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1180,22 +1178,7 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); - /* - * parse and validate reloptions for the toast - * table - */ - toast_options = transformRelOptions((Datum) 0, - cstmt->options, - "toast", - validnsps, - true, - false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); - - NewRelationCreateToastTable(address.objectId, - toast_options); + NewRelationCreateToastTable(address.objectId); } else if (IsA(stmt, CreateForeignTableStmt)) { diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 5a7afe62eab..f0d15f56525 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -37,6 +37,7 @@ static void check_new_cluster_subscription_configuration(void); static void check_old_cluster_for_valid_slots(void); static void check_old_cluster_subscription_state(void); static void check_old_cluster_global_names(ClusterInfo *cluster); +static void check_for_toast_reloptions(ClusterInfo *cluster); /* * DataTypesUsageChecks - definitions of data type checks for the old cluster @@ -634,6 +635,9 @@ check_and_dump_old_cluster(void) check_for_prepared_transactions(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 2000) + check_for_toast_reloptions(&old_cluster); + if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1700) { /* @@ -2644,3 +2648,74 @@ check_old_cluster_global_names(ClusterInfo *cluster) else check_ok(); } + +/* + * Callback function for processing results of query for + * check_for_toast_reloptions()'s UpgradeTask. If the query returned any rows + * (i.e., the check failed), write the details to the report file. + */ +static void +process_toast_relopts_check(DbInfo *dbinfo, PGresult *res, void *arg) +{ + UpgradeTaskReport *report = (UpgradeTaskReport *) arg; + int ntups = PQntuples(res); + int i_nspname = PQfnumber(res, "nspname"); + int i_relname = PQfnumber(res, "relname"); + + if (ntups == 0) + return; + + if (report->file == NULL && + (report->file = fopen_priv(report->path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", report->path); + + fprintf(report->file, "In database: %s\n", dbinfo->db_name); + + for (int rowno = 0; rowno < ntups; rowno++) + fprintf(report->file, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); +} + +/* + * Verify that no storage parameters (a.k.a. reloptions) are defined for TOAST + * tables. + */ +static void +check_for_toast_reloptions(ClusterInfo *cluster) +{ + UpgradeTaskReport report; + UpgradeTask *task = upgrade_task_create(); + const char *query = "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_class tc, " + " pg_catalog.pg_namespace n " + "WHERE c.reltoastrelid = tc.oid AND " + " c.relnamespace = c.oid AND " + " tc.reloptions IS NOT NULL"; + + prep_status("Check for tables with TOAST storage parameters"); + + report.file = NULL; + snprintf(report.path, sizeof(report.path), "%s/%s", + log_opts.basedir, + "tables_with_toast_storage_parameters.txt"); + + upgrade_task_add_step(task, query, process_toast_relopts_check, + true, &report); + upgrade_task_run(task, cluster); + upgrade_task_free(task); + + if (report.file) + { + fclose(report.file); + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains tables with TOAST storage parameters set, which is\n" + "not supported anymore. Consider remove the TOAST storage parameters using\n" + " ALTER TABLE ... RESET ( ... );\n" + "A list of tables with the problem is in the file:\n" + " %s", report.path); + } + else + check_ok(); +} diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index e8cb7f7a627..4415c1ca9b5 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -40,26 +40,22 @@ typedef enum relopt_kind { RELOPT_KIND_LOCAL = 0, RELOPT_KIND_HEAP = (1 << 0), - RELOPT_KIND_TOAST = (1 << 1), - RELOPT_KIND_BTREE = (1 << 2), - RELOPT_KIND_HASH = (1 << 3), - RELOPT_KIND_GIN = (1 << 4), - RELOPT_KIND_GIST = (1 << 5), - RELOPT_KIND_ATTRIBUTE = (1 << 6), - RELOPT_KIND_TABLESPACE = (1 << 7), - RELOPT_KIND_SPGIST = (1 << 8), - RELOPT_KIND_VIEW = (1 << 9), - RELOPT_KIND_BRIN = (1 << 10), - RELOPT_KIND_PARTITIONED = (1 << 11), + RELOPT_KIND_BTREE = (1 << 1), + RELOPT_KIND_HASH = (1 << 2), + RELOPT_KIND_GIN = (1 << 3), + RELOPT_KIND_GIST = (1 << 4), + RELOPT_KIND_ATTRIBUTE = (1 << 5), + RELOPT_KIND_TABLESPACE = (1 << 6), + RELOPT_KIND_SPGIST = (1 << 7), + RELOPT_KIND_VIEW = (1 << 8), + RELOPT_KIND_BRIN = (1 << 9), + RELOPT_KIND_PARTITIONED = (1 << 10), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; -/* reloption namespaces allowed for heaps -- currently only TOAST */ -#define HEAP_RELOPT_NAMESPACES { "toast", NULL } - /* generic struct to hold shared data */ typedef struct relopt_gen { diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 0bc61a8fee9..13e5a8affcb 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -19,10 +19,10 @@ /* * toasting.c prototypes */ -extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); -extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, +extern void NewRelationCreateToastTable(Oid relOid); +extern void NewHeapCreateToastTable(Oid relOid, LOCKMODE lockmode, Oid OIDOldToast); -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, +extern void AlterTableCreateToastTable(Oid relOid, LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 6dd22be0e8d..435e6beea0f 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2860,15 +2860,6 @@ select * from my_locks order by 1; pg_toast | ShareUpdateExclusiveLock (2 rows) -commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; - relname | max_lockmode ------------+-------------------------- - alterlock | ShareUpdateExclusiveLock - pg_toast | ShareUpdateExclusiveLock -(2 rows) - commit; begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index e3a974f2611..eff5fbece60 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -120,7 +120,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; reloptions @@ -142,9 +141,9 @@ SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions -------------------------- - {vacuum_truncate=false} + reloptions +------------ + (1 row) ALTER TABLE reloptions_test RESET (vacuum_truncate); @@ -165,56 +164,11 @@ SELECT pg_relation_size('reloptions_test') = 0; t (1 row) --- Test toast.* options -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=24} -(1 row) - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - reloptions ------------- - -(1 row) - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" --- Mix TOAST & heap -DROP TABLE reloptions_test; -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions -------------------------------------------------- - {autovacuum_vacuum_cost_delay=24,fillfactor=40} -(1 row) - -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - reloptions ------------------------------------ - {autovacuum_vacuum_cost_delay=23} -(1 row) - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; reloptions diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d4696bc3325..d551ef57d50 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -209,14 +209,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..410465dc022 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1784,10 +1784,6 @@ begin; alter table alterlock reset (fillfactor); select * from my_locks order by 1; commit; -begin; alter table alterlock set (toast.autovacuum_enabled = off); -select * from my_locks order by 1; -commit; - begin; alter table alterlock set (autovacuum_enabled = off); select * from my_locks order by 1; commit; diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 680c8bf8614..0809a2ae0e4 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -75,7 +75,6 @@ DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, - toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); @@ -94,39 +93,12 @@ INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; --- Test toast.* options -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) - WITH (toast.autovacuum_vacuum_cost_delay = 23); -SELECT reltoastrelid as toast_oid - FROM pg_class WHERE oid = 'reloptions_test'::regclass \gset -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - -ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); -SELECT reloptions FROM pg_class WHERE oid = :toast_oid; - --- Fail on non-existent options in toast namespace -CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); - --- Mix TOAST & heap -DROP TABLE reloptions_test; - -CREATE TABLE reloptions_test (s VARCHAR) WITH - (toast.autovacuum_vacuum_cost_delay = 23, - autovacuum_vacuum_cost_delay = 24, fillfactor = 40); - -SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; -SELECT reloptions FROM pg_class WHERE oid = ( - SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); - -- -- CREATE INDEX, ALTER INDEX for btrees -- +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test (s VARCHAR); CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 247b8e23b23..37a84fd9145 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -175,14 +175,6 @@ VACUUM no_index_cleanup; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; --- Only toast index is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, - toast.vacuum_index_cleanup = yes); -VACUUM no_index_cleanup; --- Only parent is cleaned up. -ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, - toast.vacuum_index_cleanup = false); -VACUUM no_index_cleanup; -- Test some extra relations. VACUUM (INDEX_CLEANUP FALSE) vaccluster; VACUUM (INDEX_CLEANUP AUTO) vactst; -- index cleanup option is ignored if no indexes -- 2.50.1 (Apple Git-155) --aHwkVxBD8x3jIwKX-- ^ permalink raw reply [nested|flat] 132+ messages in thread
end of thread, other threads:[~2026-04-07 20:30 UTC | newest] Thread overview: 132+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2019-03-28 23:50 [PATCH v1 2/8] review docs for pg12dev Justin Pryzby <pryzbyj@telsasoft.com> 2019-03-28 23:50 [PATCH v2 02/12] review docs for pg12dev Justin Pryzby <pryzbyj@telsasoft.com> 2019-03-28 23:50 [PATCH v3 01/12] review docs for pg12dev Justin Pryzby <pryzbyj@telsasoft.com> 2019-03-28 23:50 [PATCH v5 01/12] review docs for pg12dev Justin Pryzby <pryzbyj@telsasoft.com> 2023-08-23 10:19 [PATCH] use C99 named designators Alvaro Herrera <alvherre@alvh.no-ip.org> 2024-03-29 15:43 [PATCH v17] Avoid orphaned objects dependencies Bertrand Drouvot <bertranddrouvot.pg@gmail.com> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v4 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v3 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org> 2026-04-07 20:30 [PATCH v2 1/1] remove toast reloptions Nathan Bossart <nathan@postgresql.org>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox