Caveats from reloption toast_tuple_target

Started by Michael Paquieralmost 7 years ago10 messages
#1Michael Paquier
michael@paquier.xyz

Hi all,
(Adding Simon as the author of toast_tuple_target, as well Andrew and
Pavan in CC.)

toast_tuple_target has been introduced in 2017 by c251336 as of v11.
And while reviewing Pavan's patch to have more complex control over
the compression threshold of a tuple, I have bumped into some
surprising code:
/messages/by-id/20190403044916.GD3298@paquier.xyz

As far as I understand it, even with this option we don't try to toast
tuples in heap_prepare_insert() and heap_update() where
TOAST_TUPLE_THRESHOLD gets used to define if a tuple can be toasted or
not. The same applies to raw_heap_insert() in rewriteheap.c, and
needs_toast_table() in toasting.c.

Shouldn't we use the reloption instead of the compiled threshold to
determine if a tuple should be toasted or not? Perhaps I am missing
something? It seems to me that this is a bug that should be
back-patched, but it could also be qualified as a behavior change for
existing relations.

Thoughts?
--
Michael

#2Robert Haas
robertmhaas@gmail.com
In reply to: Michael Paquier (#1)
Re: Caveats from reloption toast_tuple_target

On Wed, Apr 3, 2019 at 2:38 AM Michael Paquier <michael@paquier.xyz> wrote:

Hi all,
(Adding Simon as the author of toast_tuple_target, as well Andrew and
Pavan in CC.)

toast_tuple_target has been introduced in 2017 by c251336 as of v11.
And while reviewing Pavan's patch to have more complex control over
the compression threshold of a tuple, I have bumped into some
surprising code:
/messages/by-id/20190403044916.GD3298@paquier.xyz

As far as I understand it, even with this option we don't try to toast
tuples in heap_prepare_insert() and heap_update() where
TOAST_TUPLE_THRESHOLD gets used to define if a tuple can be toasted or
not. The same applies to raw_heap_insert() in rewriteheap.c, and
needs_toast_table() in toasting.c.

Shouldn't we use the reloption instead of the compiled threshold to
determine if a tuple should be toasted or not? Perhaps I am missing
something? It seems to me that this is a bug that should be
back-patched, but it could also be qualified as a behavior change for
existing relations.

Could you explain a bit more clearly what you think the bug is?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#3Michael Paquier
michael@paquier.xyz
In reply to: Robert Haas (#2)
1 attachment(s)
Re: Caveats from reloption toast_tuple_target

On Wed, Apr 03, 2019 at 12:13:51PM -0400, Robert Haas wrote:

On Wed, Apr 3, 2019 at 2:38 AM Michael Paquier <michael@paquier.xyz> wrote:

Shouldn't we use the reloption instead of the compiled threshold to
determine if a tuple should be toasted or not? Perhaps I am missing
something? It seems to me that this is a bug that should be
back-patched, but it could also be qualified as a behavior change for
existing relations.

Could you explain a bit more clearly what you think the bug is?

I mean that toast_tuple_target is broken as-is, because it should be
used on the new tuples of a relation as a threshold to decide if this
tuple should be toasted or not, but we don't actually use the
reloption value for that decision-making: the default threshold
TOAST_TUPLE_THRESHOLD gets used instead all the time! The code does
not even create a toast table in some cases.

You may want to look at the attached patch if those words make little
sense as code may be easier to explain than words here. Here is also
a simple example:
CREATE TABLE toto (b text) WITH (toast_tuple_target = 1024);
INSERT INTO toto SELECT string_agg('', md5(random()::text))
FROM generate_series(1,10); -- 288 bytes
SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty FROM
pg_class where relname = 'toto';
INSERT INTO toto SELECT string_agg('', md5(random()::text))
FROM generate_series(1,40); -- 1248 bytes
SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty FROM
pg_class where relname = 'toto';

On HEAD, the second INSERT does *not* toast the tuple (is_empty is
true). With the patch attached, the second INSERT toasts the tuple as
I would expect (is_empty is *false*) per the custom threshold
defined.

While on it, I think that the extra argument for
RelationGetToastTupleTarget() is useless as the default value should
be TOAST_TUPLE_THRESHOLD all the time.

Does this make sense?
--
Michael

Attachments:

toast-tuple-target-fix.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 05ceb6550d..8bd544e269 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2080,6 +2080,8 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
 	/*
 	 * If the new tuple is too big for storage or contains already toasted
 	 * out-of-line attributes from some other relation, invoke the toaster.
+	 * The minimum tuple length checking if a tuple can be toasted can be
+	 * specified using the relation option toast_tuple_target.
 	 */
 	if (relation->rd_rel->relkind != RELKIND_RELATION &&
 		relation->rd_rel->relkind != RELKIND_MATVIEW)
@@ -2088,7 +2090,8 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
 		Assert(!HeapTupleHasExternal(tup));
 		return tup;
 	}
-	else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
+	else if (HeapTupleHasExternal(tup) ||
+			 tup->t_len > RelationGetToastTupleTarget(relation))
 		return toast_insert_or_update(relation, tup, NULL, options);
 	else
 		return tup;
@@ -3392,7 +3395,7 @@ l2:
 	else
 		need_toast = (HeapTupleHasExternal(&oldtup) ||
 					  HeapTupleHasExternal(newtup) ||
-					  newtup->t_len > TOAST_TUPLE_THRESHOLD);
+					  newtup->t_len > RelationGetToastTupleTarget(relation));
 
 	pagefree = PageGetHeapFreeSpace(page);
 
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index bce4274362..f5fd54ef37 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -640,6 +640,9 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
 	/*
 	 * If the new tuple is too big for storage or contains already toasted
 	 * out-of-line attributes from some other relation, invoke the toaster.
+	 * The minimum tuple length checking if a tuple can be toasted can be
+	 * specified using the relation option toast_tuple_target, so use it
+	 * if specified.
 	 *
 	 * Note: below this point, heaptup is the data we actually intend to store
 	 * into the relation; tup is the caller's original untoasted data.
@@ -650,7 +653,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
 		Assert(!HeapTupleHasExternal(tup));
 		heaptup = tup;
 	}
-	else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
+	else if (HeapTupleHasExternal(tup) ||
+			 tup->t_len > RelationGetToastTupleTarget(state->rs_new_rel))
 	{
 		int options = HEAP_INSERT_SKIP_FSM;
 
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 74e957abb7..60d37829c1 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -729,7 +729,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 		hoff += BITMAPLEN(numAttrs);
 	hoff = MAXALIGN(hoff);
 	/* now convert to a limit on the tuple data size */
-	maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff;
+	maxDataLen = RelationGetToastTupleTarget(rel) - hoff;
 
 	/*
 	 * Look for attributes with attstorage 'x' to compress.  Also find large
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 2276d3c5d3..cfa46275af 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -388,8 +388,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 /*
  * Check to see whether the table needs a TOAST table.  It does only if
  * (1) there are any toastable attributes, and (2) the maximum length
- * of a tuple could exceed TOAST_TUPLE_THRESHOLD.  (We don't want to
- * create a toast table for something like "f1 varchar(20)".)
+ * of a tuple could exceed TOAST_TUPLE_THRESHOLD or the relation option
+ * toast_tuple_target.  (We don't want to create a toast table for
+ * something like "f1 varchar(20)".)
  */
 static bool
 needs_toast_table(Relation rel)
@@ -457,5 +458,5 @@ needs_toast_table(Relation rel)
 	tuple_length = MAXALIGN(SizeofHeapTupleHeader +
 							BITMAPLEN(tupdesc->natts)) +
 		MAXALIGN(data_length);
-	return (tuple_length > TOAST_TUPLE_THRESHOLD);
+	return (tuple_length > RelationGetToastTupleTarget(rel));
 }
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 54028515a7..416b81c07c 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -275,9 +275,9 @@ typedef struct StdRdOptions
  * RelationGetToastTupleTarget
  *		Returns the relation's toast_tuple_target.  Note multiple eval of argument!
  */
-#define RelationGetToastTupleTarget(relation, defaulttarg) \
+#define RelationGetToastTupleTarget(relation) \
 	((relation)->rd_options ? \
-	 ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
+	 ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (TOAST_TUPLE_TARGET))
 
 /*
  * RelationGetFillFactor
#4Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Michael Paquier (#3)
Re: Caveats from reloption toast_tuple_target

On Thu, Apr 4, 2019 at 11:36 AM Michael Paquier <michael@paquier.xyz> wrote:

I mean that toast_tuple_target is broken as-is, because it should be
used on the new tuples of a relation as a threshold to decide if this
tuple should be toasted or not, but we don't actually use the
reloption value for that decision-making: the default threshold
TOAST_TUPLE_THRESHOLD gets used instead all the time! The code does
not even create a toast table in some cases.

I think the problem with the existing code is that while it allows users to
set toast_tuple_target to be less than TOAST_TUPLE_THRESHOLD, the same is
not honoured while deciding whether to toast a row or not. AFAICS it works
ok when toast_tuple_target is greater than or equal to
TOAST_TUPLE_THRESHOLD i.e. it won't toast the rows unless they are larger
than toast_tuple_target.

IMV it makes sense to simply cap the lower limit of toast_tuple_target to
the compile time default and update docs to reflect that. Otherwise, we
need to deal with the possibility of dynamically creating the toast table
if the relation option is lowered after creating the table. Your proposed
patch handles the case when the toast_tuple_target is specified at CREATE
TABLE, but we would still have problem with ALTER TABLE, no? But there
might be side effects of changing the lower limit for pg_dump/pg_restore.
So we would need to think about that too.

Thanks,
Pavan

--
Pavan Deolasee http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#5David Rowley
david.rowley@2ndquadrant.com
In reply to: Pavan Deolasee (#4)
Re: Caveats from reloption toast_tuple_target

On Fri, 5 Apr 2019 at 17:31, Pavan Deolasee <pavan.deolasee@gmail.com> wrote:

IMV it makes sense to simply cap the lower limit of toast_tuple_target to the compile time default and update docs to reflect that. Otherwise, we need to deal with the possibility of dynamically creating the toast table if the relation option is lowered after creating the table. Your proposed patch handles the case when the toast_tuple_target is specified at CREATE TABLE, but we would still have problem with ALTER TABLE, no? But there might be side effects of changing the lower limit for pg_dump/pg_restore. So we would need to think about that too.

FWIW I independently stumbled upon this problem today and I concluded
the same thing, we can only make the lower limit for the
toast_tuple_threshold reloption the same as TOAST_TUPLE_THRESHOLD. (I
was unaware of this thread, so I reported in [1]/messages/by-id/CAKJS1f9vrJ55oYe7un+rakTzwaGh3my5MA0RBfyNngAXu7eVeQ@mail.gmail.com)

I only quickly looked at Michael's patch and it does not seem to do
anything for the case that if no toast table exists and the user
lowers the reloption, then nothing seems to be there to build a new
toast table.

I mentioned over in [1]/messages/by-id/CAKJS1f9vrJ55oYe7un+rakTzwaGh3my5MA0RBfyNngAXu7eVeQ@mail.gmail.com that:

It does not seem possible to add/remote the toast table when the
reloption is changed either as we're only obtaining a
ShareUpdateExclusiveLock to set it. We'd likely need to upgrade that
to an AccessExclusiveLock to do that.

Reading over the original discussion in [2]/messages/by-id/CANP8+jKsVmw6CX6YP9z7zqkTzcKV1+Uzr3XjKcZW=2Ya00OyQQ@mail.gmail.com, Simon seemed more
interested in delaying the toasting for tuples larger than 2040 bytes,
not making it happen sooner. This makes sense since smaller datums are
increasingly less likely to compress the smaller they are.

The question is, can we increase the lower limit. We don't want
pg_upgrade or pg_dump reloads failing from older versions. Perhaps we
can just silently set the reloption to TOAST_TUPLE_THRESHOLD when the
user gives us some lower value. At least then lower values would
disappear over time.

[1]: /messages/by-id/CAKJS1f9vrJ55oYe7un+rakTzwaGh3my5MA0RBfyNngAXu7eVeQ@mail.gmail.com
[2]: /messages/by-id/CANP8+jKsVmw6CX6YP9z7zqkTzcKV1+Uzr3XjKcZW=2Ya00OyQQ@mail.gmail.com

--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#6David Rowley
david.rowley@2ndquadrant.com
In reply to: Pavan Deolasee (#4)
1 attachment(s)
Re: Caveats from reloption toast_tuple_target

On Fri, 5 Apr 2019 at 17:31, Pavan Deolasee <pavan.deolasee@gmail.com> wrote:

IMV it makes sense to simply cap the lower limit of toast_tuple_target to the compile time default and update docs to reflect that. Otherwise, we need to deal with the possibility of dynamically creating the toast table if the relation option is lowered after creating the table. Your proposed patch handles the case when the toast_tuple_target is specified at CREATE TABLE, but we would still have problem with ALTER TABLE, no? But there might be side effects of changing the lower limit for pg_dump/pg_restore. So we would need to think about that too.

I've attached a patch which increases the lower limit up to
TOAST_TUPLE_TARGET. Unfortunately, reloptions don't have an
assign_hook like GUCs do. Unless we add those we've no way to still
accept lower values without an error. Does anyone think that's worth
adding for this? Without it, it's possible that pg_restore /
pg_upgrade could fail if someone happened to have toast_tuple_target
set lower than 2032 bytes.

I didn't bother capping RelationGetToastTupleTarget() to ensure it
never returns less than TOAST_TUPLE_TARGET since the code that
currently uses it can't trigger if it's lower than that value.

--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

Attachments:

toast_tuple_target_fix_david.patchapplication/octet-stream; name=toast_tuple_target_fix_david.patchDownload
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 37880110e5..a9c7f41c6d 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1338,18 +1338,17 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     <term><literal>toast_tuple_target</literal> (<type>integer</type>)</term>
     <listitem>
      <para>
-      The toast_tuple_target specifies the minimum tuple length required before
-      we try to move long column values into TOAST tables, and is also the
-      target length we try to reduce the length below once toasting begins.
-      This only affects columns marked as either External or Extended
-      and applies only to new tuples - there is no effect on existing rows.
-      By default this parameter is set to allow at least 4 tuples per block,
-      which with the default blocksize will be 2040 bytes. Valid values are
-      between 128 bytes and the (blocksize - header), by default 8160 bytes.
-      Changing this value may not be useful for very short or very long rows.
-      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.
+      Allows the minimum tuple length threshold before
+      <productname>PostgreSQL</productname> will attempt to
+      <acronym>TOAST</acronym> variable length <literal>EXTERNAL</literal> and
+      <literal>EXTENDED</literal> attributes to be increased over the default
+      value.  By default, this parameter is set to allow at least 4 tuples
+      per page, which with the default page size will be 2032 bytes.  Valid
+      values range from 2032 bytes up to 8160 bytes (page size - header).
+      Increasing this value over the default allows long tuples to be kept
+      inline, however, new values for this setting, if not chosen carefully
+      can result in unusual amounts of free space being left in pages which
+      can be too small to accommodate any new tuples.
       This parameter cannot be set for TOAST tables.
      </para>
     </listitem>
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index cfbabb5265..488dbc5f80 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -312,7 +312,7 @@ static relopt_int intRelOpts[] =
 			RELOPT_KIND_HEAP,
 			ShareUpdateExclusiveLock
 		},
-		TOAST_TUPLE_TARGET, 128, TOAST_TUPLE_TARGET_MAIN
+		TOAST_TUPLE_TARGET, TOAST_TUPLE_TARGET, TOAST_TUPLE_TARGET_MAIN
 	},
 	{
 		{
#7David Rowley
david.rowley@2ndquadrant.com
In reply to: David Rowley (#6)
Re: Caveats from reloption toast_tuple_target

On Tue, 16 Apr 2019 at 23:30, David Rowley <david.rowley@2ndquadrant.com> wrote:

I've attached a patch which increases the lower limit up to
TOAST_TUPLE_TARGET. Unfortunately, reloptions don't have an
assign_hook like GUCs do. Unless we add those we've no way to still
accept lower values without an error. Does anyone think that's worth
adding for this? Without it, it's possible that pg_restore /
pg_upgrade could fail if someone happened to have toast_tuple_target
set lower than 2032 bytes.

Hi Michael,

I'm just wondering if you've had any thoughts on this?

To recap, Pavan and I think it's a problem to allow the
toast_tuple_target to be reduced as the relation in question may not
have a toast table defined. It does not seem very possible to call
create_toast_table() when the toast_tuple_target is changed since we
only obtain a ShareUpdateExclusiveLock when doing that.

The options seem to be:
1. Make the lower limit of toast_tuple_target the same as
TOAST_TUPLE_THRESHOLD; or
2. Require an AccessExclusiveLock when setting toast_tuple_target and
call create_toast_table() to ensure we get a toast table when the
setting is reduced to a level that means the target table may require
a toast relation.

I sent a patch for #1, but maybe someone thinks we should do #2? The
reason I've not explored #2 more is that after reading the original
discussion when this patch was being developed, the main interest
seemed to be keeping the values inline longer. Moving them out of
line sooner seems to make less sense since smaller values are less
likely to compress as well as larger values.

--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#8Michael Paquier
michael@paquier.xyz
In reply to: David Rowley (#7)
Re: Caveats from reloption toast_tuple_target

On Tue, Apr 30, 2019 at 02:20:27PM +1200, David Rowley wrote:

The options seem to be:
1. Make the lower limit of toast_tuple_target the same as
TOAST_TUPLE_THRESHOLD; or
2. Require an AccessExclusiveLock when setting toast_tuple_target and
call create_toast_table() to ensure we get a toast table when the
setting is reduced to a level that means the target table may require
a toast relation.

Actually, the patch I sent upthread does call create_toast_table() to
attempt to create a toast table. However it fails lamentably because
it lacks an exclusive lock when setting toast_tuple_target as you
outlined:
create table ab (a char(300));
alter table ab set (toast_tuple_target = 128);
insert into ab select string_agg('', md5(random()::text))
from generate_series(1,10); -- 288 bytes

This fails for the ALTER TABLE step like that:
ERROR: XX000: AccessExclusiveLock required to add toast table.

Now if I upgrade to AccessExclusiveLock then the thing is able to
toast tuples related to the lower threshold set. Here is the stack if
you are interested:
#0 create_toast_table (rel=0x7f8af648d178, toastOid=0,
toastIndexOid=0, reloptions=0, lockmode=8, check=true) at
toasting.c:131
#1 0x00005627da7a4eca in CheckAndCreateToastTable (relOid=16385,
reloptions=0, lockmode=8, check=true) at toasting.c:86
#2 0x00005627da7a4e1e in AlterTableCreateToastTable (relOid=16385,
reloptions=0, lockmode=8) at toasting.c:63
#3 0x00005627da87f479 in ATRewriteCatalogs (wqueue=0x7fffb77cfae8,
lockmode=8) at tablecmds.c:4185

I sent a patch for #1, but maybe someone thinks we should do #2? The
reason I've not explored #2 more is that after reading the original
discussion when this patch was being developed, the main interest
seemed to be keeping the values inline longer. Moving them out of
line sooner seems to make less sense since smaller values are less
likely to compress as well as larger values.

Yes, I have been chewing on the original thread from Simon, and it
seems really that he got interested in larger values when working on
this patch. And anyway, on HEAD we currently allow a toast table to
be created only if the threshold is at least TOAST_TUPLE_THRESHOLD,
so we have an inconsistency between reloptions.c and
needs_toast_table().

There could be an argument for allowing lower thresholds, but let's
see if somebody has a better use-case for it. In this case they would
need to upgrade the lock needed to set toast_tuple_target. I actually
don't have an argument in favor of that, thinking about it more.

Now, can we really increase the minimum value as you and Pavan
propose? For now anything between 128 and TOAST_TUPLE_TARGET gets
silently ignored, but if we increase the threshold as you propose we
could prevent some dumps to be restored, and as storage parameters are
defined as part of a WITH clause in CREATE TABLE, this could break
restores for a lot of users. We could tell pg_dump to enforce any
values between 128 and TOAST_TUPLE_THRESHOLD to be enforced to
TOAST_TUPLE_THRESHOLD, still that's a lot of complication just to take
care of one inconsistency.

Hence, based on that those arguments, there is option #3 to do
nothing. Perhaps the surrounding comments could make the current
behavior less confusing though.
--
Michael

#9David Rowley
david.rowley@2ndquadrant.com
In reply to: Michael Paquier (#8)
Re: Caveats from reloption toast_tuple_target

On Tue, 14 May 2019 at 18:49, Michael Paquier <michael@paquier.xyz> wrote:

Now, can we really increase the minimum value as you and Pavan
propose? For now anything between 128 and TOAST_TUPLE_TARGET gets
silently ignored, but if we increase the threshold as you propose we
could prevent some dumps to be restored, and as storage parameters are
defined as part of a WITH clause in CREATE TABLE, this could break
restores for a lot of users. We could tell pg_dump to enforce any
values between 128 and TOAST_TUPLE_THRESHOLD to be enforced to
TOAST_TUPLE_THRESHOLD, still that's a lot of complication just to take
care of one inconsistency.

If we had reloption validation functions then we could, but we don't,
so it seems we'd have no choice but reporting a hard ERROR.

I guess it's not impossible for pg_dump to fail on this even without
this change. If someone had increased the limit on an instance with
say 16k page to something over what TOAST_TUPLE_TARGET_MAIN would be
on a standard instance, then restoring onto the 8k page instance will
fail. Of course, that's less likely since it's a whole other factor
in the equation, and it's still not impossible, so maybe we need to
think about it harder.

Hence, based on that those arguments, there is option #3 to do
nothing. Perhaps the surrounding comments could make the current
behavior less confusing though.

I see this item has been moved to the "Nothing to do" section of the
open items list. I'd really like to see a few other people comment
before we go and ignore this. We only get 1 opportunity to release a
fix like this per year and it would be good to get further
confirmation if we want to leave this.

In my view, someone who has to go to the trouble of changing this
setting is probably going to have quite a bit of data in their
database and is quite unlikely to be using pg_dump due to that. Does
that mean we can make this cause an ERROR?... I don't know, but would
be good to hear what others think.

--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#10Michael Paquier
michael@paquier.xyz
In reply to: David Rowley (#9)
Re: Caveats from reloption toast_tuple_target

On Tue, May 21, 2019 at 12:33:54PM +1200, David Rowley wrote:

I guess it's not impossible for pg_dump to fail on this even without
this change. If someone had increased the limit on an instance with
say 16k page to something over what TOAST_TUPLE_TARGET_MAIN would be
on a standard instance, then restoring onto the 8k page instance will
fail. Of course, that's less likely since it's a whole other factor
in the equation, and it's still not impossible, so maybe we need to
think about it harder.

Sure, this one would be possible as well. Much less likely I guess as
I don't imagine a lot of our user base which perform upgrades to new
instances by changing the page size. One way to trick that would be
to use a ratio of the page size instead. I would imagine that
changing compile-time constraints when moving to a new version
increases since we have logical replication so as you can move things
with close to zero downtime without relying on the physical page
size.

I see this item has been moved to the "Nothing to do" section of the
open items list. I'd really like to see a few other people comment
before we go and ignore this. We only get 1 opportunity to release a
fix like this per year and it would be good to get further
confirmation if we want to leave this.

Yes, I moved this item without seeing any replies. Anyway, it's
really the kind of thing I'd rather not touch post beta, and I
see disadvantages in doing what you and Pavan propose as well. There
is as well the argument that tuple_toast_target is so specialized that
close to zero people are using it, hence changing its lower bound
would impact nobody.

In my view, someone who has to go to the trouble of changing this
setting is probably going to have quite a bit of data in their
database and is quite unlikely to be using pg_dump due to that. Does
that mean we can make this cause an ERROR?... I don't know, but would
be good to hear what others think.

Sure. Other opinions are welcome. Perhaps I lack insight and user
stories on the matter, but I unfortunately see downsides in all things
discussed. I am a rather pessimistic guy by nature.
--
Michael