diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index 88711e985e..35899b4a9a 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -462,9 +462,22 @@ restart: * Renumber existing enum elements to have sort positions 1..n. * * We avoid doing this unless absolutely necessary; in most installations - * it will never happen. Before we had MVCC catalog scans, this function - * posed various concurrency hazards. It no longer does, but it's still - * extra work, so we don't do it unless it's needed. + * it will never happen. The reason is that updating existing pg_enum + * entries creates hazards for other backends that are concurrently reading + * pg_enum. Although system catalog scans now use MVCC semantics, the + * syscache machinery might read different pg_enum entries under different + * snapshots, so some other backend might get confused about the proper + * ordering if a concurrent renumbering occurs. + * + * We therefore make the following choices: + * + * 1. Any code that is interested in the enumsortorder values MUST read + * all the relevant pg_enum entries with a single MVCC snapshot, or else + * acquire lock on the enum type to prevent concurrent execution of + * AddEnumLabel(). + * + * 2. Code that is not examining enumsortorder can use a syscache + * (for example, enum_in and enum_out do so). */ static void RenumberEnumType(Relation pg_enum, HeapTuple *existing, int nelems)