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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202609102
|
||||
#define CATALOG_VERSION_NO 202609111
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user