1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Add support for TOAST chunk_id type in binary upgrades

This commit adds a new SQL function able to set the type of a chunk_id
attribute for a TOAST table across binary upgrades.  The value is set
when the creation of a TOAST table is required across upgrades, in the
same fashion as the TOAST relation's oid and relfilenode.

Note that this piece currently works only with a TOAST table's chunk_id
set at OIDOID, because it is currently the only type of on-disk external
TOAST pointer supported.  This change is required for a follow-up
feature that aims to introduce support for 8-byte OIDs in external TOAST
pointers.

Taking care of this issue separately is less code churn for the next
changes, and perhaps some of the surrounding discussions with support
for different types of external on-disk TOAST pointers will find this
new facility useful.

Bump catalog version.

Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Greg Burd <greg@burd.me>
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Reviewed-by: Yugo Nagata <nagata@sraoss.co.jp>
Discussion: https://postgr.es/m/af19kUjwjhaoUTLn@paquier.xyz
This commit is contained in:
Michael Paquier
2026-09-11 10:54:48 +09:00
parent ba9e747c49
commit 34fcd735f1
8 changed files with 53 additions and 7 deletions

View File

@@ -80,6 +80,7 @@
/* Potentially set by pg_upgrade_support functions */
Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid;
Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid;
Oid binary_upgrade_next_toast_chunk_id_typoid = InvalidOid;
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber = InvalidRelFileNumber;
RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber = InvalidRelFileNumber;

View File

@@ -146,6 +146,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
int16 coloptions[2];
ObjectAddress baseobject,
toastobject;
Oid toast_chunkid_typid = OIDOID;
/*
* Is it already toasted?
@@ -184,6 +185,23 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
*/
if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid))
return false;
/*
* The attribute type for chunk_id should have been set when
* requesting a TOAST table creation.
*/
if (!OidIsValid(binary_upgrade_next_toast_chunk_id_typoid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("toast chunk_id type not set while in binary upgrade mode")));
if (binary_upgrade_next_toast_chunk_id_typoid != OIDOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot support toast chunk_id type %u in binary upgrade mode",
binary_upgrade_next_toast_chunk_id_typoid)));
toast_chunkid_typid = binary_upgrade_next_toast_chunk_id_typoid;
binary_upgrade_next_toast_chunk_id_typoid = InvalidOid;
}
/*
@@ -205,7 +223,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
tupdesc = CreateTemplateTupleDesc(3);
TupleDescInitEntry(tupdesc, (AttrNumber) 1,
"chunk_id",
OIDOID,
toast_chunkid_typid,
-1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2,
"chunk_seq",

View File

@@ -149,6 +149,17 @@ binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
Datum
binary_upgrade_set_next_toast_chunk_id_typoid(PG_FUNCTION_ARGS)
{
Oid typoid = PG_GETARG_OID(0);
CHECK_IS_BINARY_UPGRADE;
binary_upgrade_next_toast_chunk_id_typoid = typoid;
PG_RETURN_VOID();
}
Datum
binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS)
{

View File

@@ -104,6 +104,7 @@ typedef struct
RelFileNumber relfilenumber; /* object filenode */
Oid toast_oid; /* toast table OID */
RelFileNumber toast_relfilenumber; /* toast table filenode */
Oid toast_chunk_id_typoid; /* type of chunk_id attribute */
Oid toast_index_oid; /* toast table index OID */
RelFileNumber toast_index_relfilenumber; /* toast table index filenode */
} BinaryUpgradeClassOidItem;
@@ -5869,7 +5870,10 @@ collectBinaryUpgradeClassOids(Archive *fout)
const char *query;
query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
"ct.relfilenode, i.indexrelid, cti.relfilenode "
"ct.relfilenode, i.indexrelid, cti.relfilenode, "
"(SELECT a.atttypid FROM pg_attribute AS a "
" WHERE a.attrelid = c.reltoastrelid AND attname = 'chunk_id'::text) "
" AS toastchunktypid "
"FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
"ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
"LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
@@ -5891,6 +5895,7 @@ collectBinaryUpgradeClassOids(Archive *fout)
binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5));
binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6));
binaryUpgradeClassOids[i].toast_chunk_id_typoid = atooid(PQgetvalue(res, i, 7));
}
PQclear(res);
@@ -5907,7 +5912,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
/*
* Preserve the OID and relfilenumber of the table, table's index, table's
* toast table and toast table's index if any.
* toast table, toast table's chunk type and toast table's index if any.
*
* One complexity is that the current table definition might not require
* the creation of a TOAST table, but the old database might have a TOAST
@@ -5922,7 +5927,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
BinaryUpgradeClassOidItemCmp);
appendPQExpBufferStr(upgrade_buffer,
"\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
"\n-- For binary upgrade, must preserve pg_class oids, toast chunk type oids and relfilenodes\n");
if (entry->relkind != RELKIND_INDEX &&
entry->relkind != RELKIND_PARTITIONED_INDEX)
@@ -5955,6 +5960,9 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
appendPQExpBuffer(upgrade_buffer,
"SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
entry->toast_relfilenumber);
appendPQExpBuffer(upgrade_buffer,
"SELECT pg_catalog.binary_upgrade_set_next_toast_chunk_id_typoid('%u'::pg_catalog.oid);\n",
entry->toast_chunk_id_typoid);
/* every toast table has an index */
appendPQExpBuffer(upgrade_buffer,

View File

@@ -29,6 +29,7 @@ extern PGDLLIMPORT Oid binary_upgrade_next_index_pg_class_oid;
extern PGDLLIMPORT RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber;
extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_class_oid;
extern PGDLLIMPORT RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber;
extern PGDLLIMPORT Oid binary_upgrade_next_toast_chunk_id_typoid;
extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid;
extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid;

View File

@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202609102
#define CATALOG_VERSION_NO 202609111
#endif

View File

@@ -11992,6 +11992,11 @@
proname => 'binary_upgrade_set_next_toast_pg_class_oid', provolatile => 'v',
proparallel => 'r', prorettype => 'void', proargtypes => 'oid',
prosrc => 'binary_upgrade_set_next_toast_pg_class_oid' },
{ oid => '8219', descr => 'for use by pg_upgrade',
proname => 'binary_upgrade_set_next_toast_chunk_id_typoid',
provolatile => 'v', proparallel => 'r', prorettype => 'void',
proargtypes => 'oid',
prosrc => 'binary_upgrade_set_next_toast_chunk_id_typoid' },
{ oid => '3589', descr => 'for use by pg_upgrade',
proname => 'binary_upgrade_set_next_pg_enum_oid', provolatile => 'v',
proparallel => 'r', prorettype => 'void', proargtypes => 'oid',

View File

@@ -61,9 +61,10 @@ select * from t
binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid
binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid
binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid
binary_upgrade_set_next_toast_chunk_id_typoid | | binary_upgrade_set_next_toast_chunk_id_typoid
binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid
binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode
(13 rows)
(14 rows)
-- Verify clean failure when INCLUDE'd columns result in overlength tuple
-- The error message details are platform-dependent, so show only SQLSTATE
@@ -110,9 +111,10 @@ select * from t
binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid
binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid
binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid
binary_upgrade_set_next_toast_chunk_id_typoid | | binary_upgrade_set_next_toast_chunk_id_typoid
binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid
binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode
(13 rows)
(14 rows)
\set VERBOSITY sqlstate
insert into t values(repeat('xyzzy', 12), 42, repeat('xyzzy', 4000));