This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch fix_issue_1915
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit e2e6dbc1baa2d9bbca3b58487b24ecbef97c9f8e
Author: reshke <[email protected]>
AuthorDate: Fri Aug 28 18:08:49 2026 +0000

    Fix AO storage reloptions causing spurious TOAST wraparound vacuums
    
    AO tables with storage reloptions (compresstype, compresslevel, checksum,
    blocksize) had their embedded AutoVacOpts zero-filled by palloc0() because
    autovacuum reloptions are not registered for RELOPT_KIND_APPENDOPTIMIZED.
    These zero values were inherited by TOAST relations via 
extract_autovac_opts(),
    causing freeze_max_age=0 which triggers repeated aggressive wraparound
    vacuums even when the TOAST XID age is tiny.
    
    Fix: prevent extract_autovac_opts() from returning AutoVacOpts for AO parent
    relations. AO auxiliary and TOAST relations use the heap AM, so they are
    unaffected.
---
 src/backend/postmaster/autovacuum.c                | 10 +++++
 .../regress/expected/ao_relopts_autovacuum.out     | 44 ++++++++++++++++++++++
 src/test/regress/greenplum_schedule                |  1 +
 src/test/regress/sql/ao_relopts_autovacuum.sql     | 37 ++++++++++++++++++
 4 files changed, 92 insertions(+)

diff --git a/src/backend/postmaster/autovacuum.c 
b/src/backend/postmaster/autovacuum.c
index f517cb4d006..5fc1927fb2c 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2957,6 +2957,16 @@ extract_autovac_opts(HeapTuple tup, TupleDesc 
pg_class_desc)
                relam != AO_COLUMN_TABLE_AM_OID)
                return NULL;
 
+       /*
+        * AO reloptions use RELOPT_KIND_APPENDOPTIMIZED which does not include
+        * autovacuum reloptions, so the embedded AutoVacOpts is zero-filled.
+        * Returning it would make TOAST inherit freeze_max_age=0, triggering
+        * spurious aggressive wraparound vacuums.  AO auxiliary and TOAST
+        * relations use the heap AM, so they are unaffected by this guard.
+        */
+       if (IsAccessMethodAO(relam))
+               return NULL;
+
        relopts = extractRelOptions(tup, pg_class_desc, tam->amoptions);
        if (relopts == NULL)
                return NULL;
diff --git a/src/test/regress/expected/ao_relopts_autovacuum.out 
b/src/test/regress/expected/ao_relopts_autovacuum.out
new file mode 100644
index 00000000000..006b8a82452
--- /dev/null
+++ b/src/test/regress/expected/ao_relopts_autovacuum.out
@@ -0,0 +1,44 @@
+-- AO storage reloptions must not produce zeroed autovacuum options
+-- that get inherited by the TOAST relation.
+CREATE SCHEMA ao_relopts_av_test;
+SET search_path = ao_relopts_av_test;
+CREATE TABLE ao_row_with_storage_opts
+(
+    id integer,
+    payload text
+)
+WITH
+(
+    appendonly=true,
+    orientation=row,
+    compresstype=zlib,
+    compresslevel=1,
+    checksum=true
+)
+DISTRIBUTED RANDOMLY;
+INSERT INTO ao_row_with_storage_opts VALUES (1, repeat('x', 10000));
+-- Parent has only storage reloptions.
+SELECT option_name, option_value
+FROM pg_options_to_table(
+    (SELECT reloptions FROM pg_class
+     WHERE oid = 'ao_row_with_storage_opts'::regclass))
+ORDER BY option_name;
+  option_name  | option_value 
+---------------+--------------
+ checksum      | true
+ compresslevel | 1
+ compresstype  | zlib
+(3 rows)
+
+-- TOAST has no reloptions of its own.
+SELECT t.reloptions IS NULL AS toast_no_reloptions
+FROM pg_class c
+JOIN pg_class t ON t.oid = c.reltoastrelid
+WHERE c.oid = 'ao_row_with_storage_opts'::regclass;
+ toast_no_reloptions 
+---------------------
+ t
+(1 row)
+
+DROP SCHEMA ao_relopts_av_test CASCADE;
+NOTICE:  drop cascades to table ao_row_with_storage_opts
diff --git a/src/test/regress/greenplum_schedule 
b/src/test/regress/greenplum_schedule
index 84e8766844b..ccaf5a98033 100755
--- a/src/test/regress/greenplum_schedule
+++ b/src/test/regress/greenplum_schedule
@@ -21,6 +21,7 @@
 test: autovacuum
 test: autovacuum-segment
 test: autovacuum-template0-segment
+test: ao_relopts_autovacuum
 
 # check profile feature
 test: profile
diff --git a/src/test/regress/sql/ao_relopts_autovacuum.sql 
b/src/test/regress/sql/ao_relopts_autovacuum.sql
new file mode 100644
index 00000000000..1134338553e
--- /dev/null
+++ b/src/test/regress/sql/ao_relopts_autovacuum.sql
@@ -0,0 +1,37 @@
+-- AO storage reloptions must not produce zeroed autovacuum options
+-- that get inherited by the TOAST relation.
+
+CREATE SCHEMA ao_relopts_av_test;
+SET search_path = ao_relopts_av_test;
+
+CREATE TABLE ao_row_with_storage_opts
+(
+    id integer,
+    payload text
+)
+WITH
+(
+    appendonly=true,
+    orientation=row,
+    compresstype=zlib,
+    compresslevel=1,
+    checksum=true
+)
+DISTRIBUTED RANDOMLY;
+
+INSERT INTO ao_row_with_storage_opts VALUES (1, repeat('x', 10000));
+
+-- Parent has only storage reloptions.
+SELECT option_name, option_value
+FROM pg_options_to_table(
+    (SELECT reloptions FROM pg_class
+     WHERE oid = 'ao_row_with_storage_opts'::regclass))
+ORDER BY option_name;
+
+-- TOAST has no reloptions of its own.
+SELECT t.reloptions IS NULL AS toast_no_reloptions
+FROM pg_class c
+JOIN pg_class t ON t.oid = c.reltoastrelid
+WHERE c.oid = 'ao_row_with_storage_opts'::regclass;
+
+DROP SCHEMA ao_relopts_av_test CASCADE;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to