mirror of
https://github.com/postgres/postgres.git
synced 2026-10-25 01:39:28 +03:00
Restrict REPACK (CONCURRENTLY) to the heap access method.
REPACK (CONCURRENTLY) didn't check the table AM of the table being repacked, so if the table AM doesn't support logical decoding, the concurrent changes are never decoded and are silently lost from the rewritten table. Fix by erroring out for tables that use a non-heap access method. Reported-by: Nathan Bossart <nathandbossart@gmail.com> Author: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Nathan Bossart <nathandbossart@gmail.com> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Discussion: https://postgr.es/m/apBkixO4xAGFoiT3@nathan Backpatch-through: 19
This commit is contained in:
@@ -285,6 +285,12 @@ REPACK [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] USING
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The table's access method is not <literal>heap</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<command>REPACK</command> is executed inside a transaction block.
|
||||
|
||||
@@ -888,6 +888,20 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
|
||||
errdetail("%s requires \"wal_level\" to be set to \"replica\" or higher.",
|
||||
"REPACK (CONCURRENTLY)"));
|
||||
|
||||
/*
|
||||
* A table AM that doesn't support logical decoding would cause REPACK
|
||||
* (CONCURRENTLY) to silently lose the changes made during the rewrite.
|
||||
* Nothing in TableAmRoutine tells us whether it does, so for now restrict
|
||||
* to heap. Check the routine rather than the AM OID, so that an AM
|
||||
* reusing the heap handler still works.
|
||||
*/
|
||||
if (rel->rd_tableam != GetHeapamTableAmRoutine())
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot execute %s on relation \"%s\"",
|
||||
"REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
|
||||
errdetail("This operation is only supported for the \"heap\" access method."));
|
||||
|
||||
/* Data changes in system relations are not logically decoded. */
|
||||
if (IsCatalogRelation(rel))
|
||||
ereport(ERROR,
|
||||
|
||||
Reference in New Issue
Block a user