aboutsummaryrefslogtreecommitdiff
path: root/src/backend/replication
diff options
context:
space:
mode:
authorNathan Bossart <nathan@postgresql.org>2025-05-07 14:47:36 -0500
committerNathan Bossart <nathan@postgresql.org>2025-05-07 14:47:36 -0500
commit16bf24e0e471c975f0877d6612eacdae7ce4a30e (patch)
tree0ce1620d597b90d28fb6b428693df925a21347c8 /src/backend/replication
parent5f4d98d4f3718cf7a0597c37f3ee4a4485de6ef8 (diff)
downloadpostgresql-16bf24e0e471c975f0877d6612eacdae7ce4a30e.tar.gz
postgresql-16bf24e0e471c975f0877d6612eacdae7ce4a30e.zip
Remove pg_replication_origin's TOAST table.
A few places that access this catalog don't set up an active snapshot before potentially accessing its TOAST table. However, roname (the replication origin name) is the only varlena column, so this is only a problem if the name requires out-of-line storage. This commit removes its TOAST table to avoid needing to set up a snapshot. It also places a limit on replication origin names so that attempts to set long names will fail with a more user-friendly error. Those chosen limit of 512 bytes should be sufficient to avoid "row is too big" errors independent of BLCKSZ, but it should also be lenient enough for all reasonable use-cases. Bumps catversion. Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Reviewed-by: Euler Taveira <euler@eulerto.com> Reviewed-by: Nisha Moond <nisha.moond412@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/ZvMSUPOqUU-VNADN%40nathan
Diffstat (limited to 'src/backend/replication')
-rw-r--r--src/backend/replication/logical/origin.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 6583dd497da..a17bacf88e7 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -264,6 +264,18 @@ replorigin_create(const char *roname)
SysScanDesc scan;
ScanKeyData key;
+ /*
+ * To avoid needing a TOAST table for pg_replication_origin, we limit
+ * replication origin names to 512 bytes. This should be more than enough
+ * for all practical use.
+ */
+ if (strlen(roname) > MAX_RONAME_LEN)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("replication origin name is too long"),
+ errdetail("Replication origin names must be no longer than %d bytes.",
+ MAX_RONAME_LEN)));
+
roname_d = CStringGetTextDatum(roname);
Assert(IsTransactionState());
@@ -287,6 +299,17 @@ replorigin_create(const char *roname)
rel = table_open(ReplicationOriginRelationId, ExclusiveLock);
+ /*
+ * We want to be able to access pg_replication_origin without setting up a
+ * snapshot. To make that safe, it needs to not have a TOAST table, since
+ * TOASTed data cannot be fetched without a snapshot. As of this writing,
+ * its only varlena column is roname, which we limit to 512 bytes to avoid
+ * needing out-of-line storage. If you add a TOAST table to this catalog,
+ * be sure to set up a snapshot everywhere it might be needed. For more
+ * information, see https://postgr.es/m/ZvMSUPOqUU-VNADN%40nathan.
+ */
+ Assert(!OidIsValid(rel->rd_rel->reltoastrelid));
+
for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++)
{
bool nulls[Natts_pg_replication_origin];