Support for 8-byte TOAST values, round two - Mailing list pgsql-hackers

From Michael Paquier
Subject Support for 8-byte TOAST values, round two
Date
Msg-id af19kUjwjhaoUTLn@paquier.xyz
Whole thread
List pgsql-hackers
Hi all,

This is a follow-up of the previous thread about $subject, with a
reworked patch set for discussion in v20, as I care about the subject:
https://www.postgresql.org/message-id/aFOnKHG7Wn-Srnpv@paquier.xyz

The main feedback of the previous thread is that the previous
implementation with its callbacks for each vartag was not liked much,
and their were concerns with pointer redirections and performance.
This patch set uses what I am calling the "brutal" approach, relying
on a vartag_external of a varlena or the atttype of the TOAST relation
to decide which external toast pointer we should use.  This uses no
function pointers, and patches the code to deal with Oid or Oid8 TOAST
values where it matters.  So, this time, performance cannot really be
an issue.

The patch set is structured so as all the ground work happens first
(most of it comes from the previous patch set, reorganized a bit), and
the introduction of the varatt pieces are last, based on the following
rules:
- A table can use a 8-byte TOAST value with a new reloption, named
toast_value_type that can be set to "oid" (default) or "oid8",
creating a TOAST table with a value of the assigned type.  This
includes support for dumps as well as binary upgrades, so as the
atttype of the chunk_id of the TOAST table is preserved.  A table with
a TOAST type assigned cannot be changed to a different type through a
VACUUM FULL or a rewrite, as a matter of implementation simplicity.
- Renames and cleanup of various areas related to varatt_external,
renaming things to use OID.
- The 8-byte TOAST values rely on a Oid8, whose value is retrieved
from the control file extended by 4 bytes.  The code supports
wraparound of values so as we don't assign anything between 0 and
FirstNormalObjectId for the lower bytes, same way as before.

The last patch introduces a new vartag_external and the new
varatt_external_oid8, with an Oid8 as value.  Well, not exactly, the
patch uses two uint32 fields so as the structure is packed without
padding, as of:
typedef struct varatt_external_oid8
{
   int32       va_rawsize;
   uint32      va_extinfo;
   uint32      va_valueid_lo;
   uint32      va_valueid_hi;
   Oid         va_toastrelid;
} varatt_external_oid8;

Note that if applying all the patches except the last one, the code
would use an varatt_external_oid with an oid8 TOAST table.  This
works, the split is to make reviews easier.  An oid8 TOAST table
always uses a varatt_external_oid8.

I have done a lot of back-and-forth in the patch to try to find a good
balance between the manipulation of the varlenas in the detoast and
compression paths, as well as reorderbuffer.c and amcheck.  And I have
finished with the attached, which is kind of nice.  The last patch has
a low footprint:
9 files changed, 537 insertions(+), 208 deletions(-)

Happy to discuss about all that at pgconf.dev.  This is of course
intended for v20, added to the next CF.
Thanks,
--
Michael

Attachment

pgsql-hackers by date:

Previous
From: Alexander Pyhalov
Date:
Subject: Re: Function scan FDW pushdown
Next
From: Michael Paquier
Date:
Subject: Re: Fix bug with accessing to temporary tables of other sessions