Subject: [PATCH 1/2] pageinspect: Reject unlogged TOAST reads during recovery A saved heap page can contain an external TOAST pointer even when the page image itself is available from logged storage on a standby. Both heap_page_item_attrs() and tuple_data_split() can therefore reach missing unlogged storage without calling get_raw_page() on that standby. Check before detoasting an on-disk external value and report the same error and SQLSTATE as the other recovery guards. Leave inline values and decoding without detoasting available. Applies on top of the four v1 patches in CF #7478. --- contrib/pageinspect/heapfuncs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c index 7be4770dc84b798f947496cfd5b5b2c18bab8f80..57068eca2ddb0c1d53a30b50aebb34c70e41c45b 100644 --- a/contrib/pageinspect/heapfuncs.c +++ b/contrib/pageinspect/heapfuncs.c @@ -27,6 +27,7 @@ #include "access/htup_details.h" #include "access/relation.h" +#include "access/xlog.h" #include "catalog/pg_am_d.h" #include "catalog/pg_type.h" #include "funcapi.h" @@ -389,7 +390,16 @@ tuple_data_split_internal(Oid relid, char *tupdata, errmsg("unexpected end of tuple data"))); if (attr->attlen == -1 && do_detoast) + { + /* A saved page can still refer to unlogged TOAST storage. */ + if (VARATT_IS_EXTERNAL_ONDISK(tupdata + off) && + !RelationIsPermanent(rel) && RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot access temporary or unlogged relations during recovery"))); + attr_data = pg_detoast_datum_copy((varlena *) (tupdata + off)); + } else { attr_data = (bytea *) palloc(len + VARHDRSZ);