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

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

commit 1073dbdf59b26d11c5e5389514a5da7c3b16bd5c
Author: Zhenghua Lyu <[email protected]>
AuthorDate: Tue Oct 25 11:45:57 2022 +0800

    Invalidate CatCache in AbortTransaction to clear reader gang's cache. 
(#14048)
    
    In AbortTransaction, Postgres does not need to tell other backend to
    invalidate catcache because the change is invisible. However,
    Greenplum's MPP architecture has writer gang, reader gangs and gangs
    can be reused in the same session. Only writer gang can modify
    catalogs, thus in Greenplum we have to tell other backends (reader
    gangs) when abort transaction.
    
    Discussion: 
https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/u3-D7isdvmM
    
    Authored-by: David Kimura <[email protected]>
---
 src/backend/access/transam/xact.c                  | 15 ++++-
 src/test/regress/expected/catcache.out             | 63 ++++++++++++++++++++
 src/test/regress/expected/catcache_optimizer.out   | 67 ++++++++++++++++++++++
 src/test/regress/expected/qp_union_intersect.out   |  3 -
 .../expected/qp_union_intersect_optimizer.out      |  3 -
 src/test/regress/greenplum_schedule                |  1 +
 src/test/regress/sql/catcache.sql                  | 25 ++++++++
 src/test/regress/sql/qp_union_intersect.sql        |  3 -
 8 files changed, 170 insertions(+), 10 deletions(-)

diff --git a/src/backend/access/transam/xact.c 
b/src/backend/access/transam/xact.c
index 12355b4749..a99d333ef0 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -3629,7 +3629,20 @@ AbortTransaction(void)
                AtEOXact_ComboCid_Dsm_Detach();
                AtEOXact_Buffers(false);
                AtEOXact_RelationCache(false);
-               AtEOXact_Inval(false);
+               /*
+                * Greenplum specific behavior:
+                *   We pass is_commit to true even we are here Aborting 
Transaction.
+                *   Greenplum has writer gang and reader gangs, only writer 
gang can
+                *   modify database (like catalog ...), and gang can be reused 
in
+                *   Greenplum in the same session. Thus when we abort a 
transaction,
+                *   we still have to tell other reader gangs to abort those 
catcaches.
+                *   EntryDB is reader gang in coordinator, we also want to 
tell them
+                *   to invalidate catcache when QD abort.
+                *   Discussion: 
https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/u3-D7isdvmM
+                */
+               bool need_inval_even_for_abort = ((Gp_role == GP_ROLE_EXECUTE 
&& Gp_is_writer) ||
+                                                                               
  Gp_role == GP_ROLE_DISPATCH); /* test QD to invalidate entryDB's catcache */
+               AtEOXact_Inval(need_inval_even_for_abort);
                AtEOXact_MultiXact();
 
                ResourceOwnerRelease(TopTransactionResourceOwner,
diff --git a/src/test/regress/expected/catcache.out 
b/src/test/regress/expected/catcache.out
new file mode 100644
index 0000000000..b6bcf2ac4b
--- /dev/null
+++ b/src/test/regress/expected/catcache.out
@@ -0,0 +1,63 @@
+-- Test abort transaction should invalidate reader gang's cat cache
+-- Discussion: 
https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/u3-D7isdvmM
+set optimizer_force_multistage_agg = 1;
+create table dml_14027_union_s (a int not null, b numeric default 10.00) 
distributed by (a) partition by range(b);
+create table dml_14027_union_s_1_prt_2 partition of dml_14027_union_s for 
values from (1) to (1001);
+NOTICE:  table has parent, setting distribution columns to match parent table
+create table dml_14027_union_s_1_prt_def partition of dml_14027_union_s 
default;
+NOTICE:  table has parent, setting distribution columns to match parent table
+insert into dml_14027_union_s select generate_series(1,1), 
generate_series(1,1);
+begin;
+drop table dml_14027_union_s_1_prt_def;
+explain select count(distinct(b)) from dml_14027_union_s;
+                                                              QUERY PLAN       
                                                       
+--------------------------------------------------------------------------------------------------------------------------------------
+ Finalize Aggregate  (cost=321.22..321.23 rows=1 width=8)
+   ->  Gather Motion 3:1  (slice1; segments: 3)  (cost=321.17..321.22 rows=3 
width=8)
+         ->  Partial Aggregate  (cost=321.17..321.18 rows=1 width=8)
+               ->  HashAggregate  (cost=317.00..320.33 rows=333 width=32)
+                     Group Key: dml_14027_union_s.b
+                     ->  Redistribute Motion 3:3  (slice2; segments: 3)  
(cost=282.00..312.00 rows=1000 width=32)
+                           Hash Key: dml_14027_union_s.b
+                           ->  Streaming HashAggregate  (cost=282.00..292.00 
rows=1000 width=32)
+                                 Group Key: dml_14027_union_s.b
+                                 ->  Seq Scan on dml_14027_union_s_1_prt_2 
dml_14027_union_s  (cost=0.00..199.33 rows=16533 width=32)
+ Optimizer: Postgres query optimizer
+(11 rows)
+
+select count(distinct(b)) from dml_14027_union_s;
+ count 
+-------
+     1
+(1 row)
+
+rollback;
+explain update dml_14027_union_s set a = (select null union select 
null)::numeric;
+                                                          QUERY PLAN           
                                               
+------------------------------------------------------------------------------------------------------------------------------
+ Update on dml_14027_union_s  (cost=0.07..2134.74 rows=0 width=0)
+   Update on dml_14027_union_s_1_prt_2 dml_14027_union_s_1
+   Update on dml_14027_union_s_1_prt_def dml_14027_union_s_2
+   InitPlan 1 (returns $0)  (slice2)
+     ->  Unique  (cost=0.06..0.07 rows=2 width=32)
+           Group Key: (NULL::text)
+           ->  Sort  (cost=0.06..0.07 rows=2 width=32)
+                 Sort Key: (NULL::text)
+                 ->  Append  (cost=0.00..0.05 rows=2 width=32)
+                       ->  Result  (cost=0.00..0.01 rows=1 width=32)
+                       ->  Result  (cost=0.00..0.01 rows=1 width=32)
+   ->  Explicit Redistribute Motion 3:3  (slice1; segments: 3)  
(cost=0.00..2134.67 rows=66133 width=50)
+         ->  Split  (cost=0.00..812.00 rows=66133 width=50)
+               ->  Append  (cost=0.00..812.00 rows=33067 width=50)
+                     ->  Seq Scan on dml_14027_union_s_1_prt_2 
dml_14027_union_s_1  (cost=0.00..323.33 rows=16533 width=50)
+                     ->  Seq Scan on dml_14027_union_s_1_prt_def 
dml_14027_union_s_2  (cost=0.00..323.33 rows=16533 width=50)
+ Optimizer: Postgres query optimizer
+(17 rows)
+
+-- Should not raise error due to stale catcache in reader gang.
+-- eg: ERROR: expected partdefid 134733, but got 0
+update dml_14027_union_s set a = (select null union select null)::numeric;
+ERROR:  null value in column "a" of relation "dml_14027_union_s_1_prt_2" 
violates not-null constraint  (seg0 127.0.0.1:7002 pid=1992175)
+DETAIL:  Failing row contains (null, 1).
+drop table dml_14027_union_s;
+reset optimizer_force_multistage_agg;
diff --git a/src/test/regress/expected/catcache_optimizer.out 
b/src/test/regress/expected/catcache_optimizer.out
new file mode 100644
index 0000000000..b4e31b7188
--- /dev/null
+++ b/src/test/regress/expected/catcache_optimizer.out
@@ -0,0 +1,67 @@
+-- Test abort transaction should invalidate reader gang's cat cache
+-- Discussion: 
https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/u3-D7isdvmM
+set optimizer_force_multistage_agg = 1;
+create table dml_14027_union_s (a int not null, b numeric default 10.00) 
distributed by (a) partition by range(b);
+create table dml_14027_union_s_1_prt_2 partition of dml_14027_union_s for 
values from (1) to (1001);
+NOTICE:  table has parent, setting distribution columns to match parent table
+create table dml_14027_union_s_1_prt_def partition of dml_14027_union_s 
default;
+NOTICE:  table has parent, setting distribution columns to match parent table
+insert into dml_14027_union_s select generate_series(1,1), 
generate_series(1,1);
+begin;
+drop table dml_14027_union_s_1_prt_def;
+explain select count(distinct(b)) from dml_14027_union_s;
+                                                     QUERY PLAN                
                                      
+---------------------------------------------------------------------------------------------------------------------
+ Aggregate  (cost=0.00..431.00 rows=1 width=8)
+   ->  Gather Motion 3:1  (slice1; segments: 3)  (cost=0.00..431.00 rows=1 
width=8)
+         ->  GroupAggregate  (cost=0.00..431.00 rows=1 width=8)
+               Group Key: b
+               ->  Sort  (cost=0.00..431.00 rows=1 width=8)
+                     Sort Key: b
+                     ->  Redistribute Motion 3:3  (slice2; segments: 3)  
(cost=0.00..431.00 rows=1 width=8)
+                           Hash Key: b
+                           ->  GroupAggregate  (cost=0.00..431.00 rows=1 
width=8)
+                                 Group Key: b
+                                 ->  Sort  (cost=0.00..431.00 rows=1 width=8)
+                                       Sort Key: b
+                                       ->  Dynamic Seq Scan on 
dml_14027_union_s  (cost=0.00..431.00 rows=1 width=8)
+                                             Number of partitions to scan: 1 
(out of 1)
+ Optimizer: Pivotal Optimizer (GPORCA)
+(15 rows)
+
+select count(distinct(b)) from dml_14027_union_s;
+ count 
+-------
+     1
+(1 row)
+
+rollback;
+explain update dml_14027_union_s set a = (select null union select 
null)::numeric;
+                                                          QUERY PLAN           
                                               
+------------------------------------------------------------------------------------------------------------------------------
+ Update on dml_14027_union_s  (cost=0.07..2134.74 rows=0 width=0)
+   Update on dml_14027_union_s_1_prt_2 dml_14027_union_s_1
+   Update on dml_14027_union_s_1_prt_def dml_14027_union_s_2
+   InitPlan 1 (returns $0)  (slice2)
+     ->  Unique  (cost=0.06..0.07 rows=2 width=32)
+           Group Key: (NULL::text)
+           ->  Sort  (cost=0.06..0.07 rows=2 width=32)
+                 Sort Key: (NULL::text)
+                 ->  Append  (cost=0.00..0.05 rows=2 width=32)
+                       ->  Result  (cost=0.00..0.01 rows=1 width=32)
+                       ->  Result  (cost=0.00..0.01 rows=1 width=32)
+   ->  Explicit Redistribute Motion 3:3  (slice1; segments: 3)  
(cost=0.00..2134.67 rows=66133 width=50)
+         ->  Split  (cost=0.00..812.00 rows=66133 width=50)
+               ->  Append  (cost=0.00..812.00 rows=33067 width=50)
+                     ->  Seq Scan on dml_14027_union_s_1_prt_2 
dml_14027_union_s_1  (cost=0.00..323.33 rows=16533 width=50)
+                     ->  Seq Scan on dml_14027_union_s_1_prt_def 
dml_14027_union_s_2  (cost=0.00..323.33 rows=16533 width=50)
+ Optimizer: Postgres query optimizer
+(17 rows)
+
+-- Should not raise error due to stale catcache in reader gang.
+-- eg: ERROR: expected partdefid 134733, but got 0
+update dml_14027_union_s set a = (select null union select null)::numeric;
+ERROR:  null value in column "a" of relation "dml_14027_union_s_1_prt_2" 
violates not-null constraint  (seg0 127.0.0.1:7002 pid=1872432)
+DETAIL:  Failing row contains (null, 1).
+drop table dml_14027_union_s;
+reset optimizer_force_multistage_agg;
diff --git a/src/test/regress/expected/qp_union_intersect.out 
b/src/test/regress/expected/qp_union_intersect.out
index 5b90963bb6..6df35ddaa8 100644
--- a/src/test/regress/expected/qp_union_intersect.out
+++ b/src/test/regress/expected/qp_union_intersect.out
@@ -1687,8 +1687,6 @@ rollback;
 -- @description union_update_test28: Negative Tests Update the partition key 
to an out of dml_union_range value with no default partition
 begin;
 DROP TABLE dml_union_s_1_prt_def;
--- GPDB_12_MERGE_FIXME: This test case is flaky, ERROR:  expected partdefid 
134733, but got 0 (partdesc.c:194)
-set optimizer=off;
 SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
  count 
 -------
@@ -1701,7 +1699,6 @@ DETAIL:  Partition key of the failing row contains (d) = 
(null).
 --SELECT DISTINCT(d) FROM dml_union_s;
 --SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
 rollback;
-reset optimizer;
 -- @description union_update_test29: Negative Tests  UPDATE violates the CHECK 
constraint on the column
 SELECT COUNT(DISTINCT(b)) FROM dml_union_s;
  count 
diff --git a/src/test/regress/expected/qp_union_intersect_optimizer.out 
b/src/test/regress/expected/qp_union_intersect_optimizer.out
index 26a8fb71c6..9041d5fe05 100644
--- a/src/test/regress/expected/qp_union_intersect_optimizer.out
+++ b/src/test/regress/expected/qp_union_intersect_optimizer.out
@@ -1688,8 +1688,6 @@ rollback;
 -- @description union_update_test28: Negative Tests Update the partition key 
to an out of dml_union_range value with no default partition
 begin;
 DROP TABLE dml_union_s_1_prt_def;
--- GPDB_12_MERGE_FIXME: This test case is flaky, ERROR:  expected partdefid 
134733, but got 0 (partdesc.c:194)
-set optimizer=off;
 SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
  count 
 -------
@@ -1702,7 +1700,6 @@ DETAIL:  Partition key of the failing row contains (d) = 
(null).
 --SELECT DISTINCT(d) FROM dml_union_s;
 --SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
 rollback;
-reset optimizer;
 -- @description union_update_test29: Negative Tests  UPDATE violates the CHECK 
constraint on the column
 SELECT COUNT(DISTINCT(b)) FROM dml_union_s;
  count 
diff --git a/src/test/regress/greenplum_schedule 
b/src/test/regress/greenplum_schedule
index 763b5952c9..23907d758d 100755
--- a/src/test/regress/greenplum_schedule
+++ b/src/test/regress/greenplum_schedule
@@ -179,6 +179,7 @@ test: direct_dispatch bfv_dd bfv_dd_multicolumn bfv_dd_types
 test: interrupt_holdoff_count
 
 test: bfv_catalog bfv_index bfv_olap bfv_aggregate bfv_partition_plans 
DML_over_joins bfv_statistic nested_case_null sort bb_mpph 
aggregate_with_groupingsets gporca gpsd part_external_table
+test: catcache
 # Run minirepro separately to avoid concurrent deletes erroring out the 
internal pg_dump call
 test: minirepro
 
diff --git a/src/test/regress/sql/catcache.sql 
b/src/test/regress/sql/catcache.sql
new file mode 100644
index 0000000000..1a4ecb3a99
--- /dev/null
+++ b/src/test/regress/sql/catcache.sql
@@ -0,0 +1,25 @@
+-- Test abort transaction should invalidate reader gang's cat cache
+-- Discussion: 
https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/u3-D7isdvmM
+
+set optimizer_force_multistage_agg = 1;
+
+create table dml_14027_union_s (a int not null, b numeric default 10.00) 
distributed by (a) partition by range(b);
+create table dml_14027_union_s_1_prt_2 partition of dml_14027_union_s for 
values from (1) to (1001);
+create table dml_14027_union_s_1_prt_def partition of dml_14027_union_s 
default;
+
+insert into dml_14027_union_s select generate_series(1,1), 
generate_series(1,1);
+
+begin;
+drop table dml_14027_union_s_1_prt_def;
+explain select count(distinct(b)) from dml_14027_union_s;
+select count(distinct(b)) from dml_14027_union_s;
+rollback;
+
+explain update dml_14027_union_s set a = (select null union select 
null)::numeric;
+-- Should not raise error due to stale catcache in reader gang.
+-- eg: ERROR: expected partdefid 134733, but got 0
+update dml_14027_union_s set a = (select null union select null)::numeric;
+
+drop table dml_14027_union_s;
+
+reset optimizer_force_multistage_agg;
diff --git a/src/test/regress/sql/qp_union_intersect.sql 
b/src/test/regress/sql/qp_union_intersect.sql
index 1872734b6b..d38f6221ad 100644
--- a/src/test/regress/sql/qp_union_intersect.sql
+++ b/src/test/regress/sql/qp_union_intersect.sql
@@ -619,14 +619,11 @@ rollback;
 -- @description union_update_test28: Negative Tests Update the partition key 
to an out of dml_union_range value with no default partition
 begin;
 DROP TABLE dml_union_s_1_prt_def;
--- GPDB_12_MERGE_FIXME: This test case is flaky, ERROR:  expected partdefid 
134733, but got 0 (partdesc.c:194)
-set optimizer=off;
 SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
 UPDATE dml_union_s SET d = (SELECT NULL EXCEPT SELECT NULL)::numeric; 
 --SELECT DISTINCT(d) FROM dml_union_s;
 --SELECT COUNT(DISTINCT(d)) FROM dml_union_s;
 rollback;
-reset optimizer;
 
 -- @description union_update_test29: Negative Tests  UPDATE violates the CHECK 
constraint on the column
 SELECT COUNT(DISTINCT(b)) FROM dml_union_s;


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

Reply via email to