From 794025eff0db181e463cb92d4b1aedd0879c88a6 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Wed, 25 Aug 2021 09:23:27 +0530 Subject: Fix toast rewrites in logical decoding. Commit 325f2ec555 introduced pg_class.relwrite to skip operations on tables created as part of a heap rewrite during DDL. It links such transient heaps to the original relation OID via this new field in pg_class but forgot to do anything about toast tables. So, logical decoding was not able to skip operations on internally created toast tables. This leads to an error when we tried to decode the WAL for the next operation for which it appeared that there is a toast data where actually it didn't have any toast data. To fix this, we set pg_class.relwrite for internally created toast tables as well which allowed skipping operations on them during logical decoding. Author: Bertrand Drouvot Reviewed-by: David Zhang, Amit Kapila Backpatch-through: 11, where it was introduced Discussion: https://postgr.es/m/b5146fb1-ad9e-7d6e-f980-98ed68744a7c@amazon.com --- src/backend/commands/tablecmds.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/backend/commands/tablecmds.c') diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8784bec0e6d..b149f2e9d83 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3562,6 +3562,37 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal, bo relation_close(targetrelation, NoLock); } +/* + * ResetRelRewrite - reset relrewrite + */ +void +ResetRelRewrite(Oid myrelid) +{ + Relation relrelation; /* for RELATION relation */ + HeapTuple reltup; + Form_pg_class relform; + + /* + * Find relation's pg_class tuple. + */ + relrelation = table_open(RelationRelationId, RowExclusiveLock); + + reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid)); + if (!HeapTupleIsValid(reltup)) /* shouldn't happen */ + elog(ERROR, "cache lookup failed for relation %u", myrelid); + relform = (Form_pg_class) GETSTRUCT(reltup); + + /* + * Update pg_class tuple. + */ + relform->relrewrite = InvalidOid; + + CatalogTupleUpdate(relrelation, &reltup->t_self, reltup); + + heap_freetuple(reltup); + table_close(relrelation, RowExclusiveLock); +} + /* * Disallow ALTER TABLE (and similar commands) when the current backend has * any open reference to the target table besides the one just acquired by -- cgit v1.2.3