diff --git a/contrib/pax_storage/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out b/contrib/pax_storage/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out index ae21059fcb6..1e011ecec22 100644 --- a/contrib/pax_storage/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out +++ b/contrib/pax_storage/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out @@ -33,8 +33,8 @@ CREATE -- verify_cpu_usage: calculate each QE's average cpu usage using all the data in -- the table cpu_usage_sample. And compare the average value to the expected value. -- return true if the practical value is close to the expected value. -CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json import functools -all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) usage = float(all_info[0]['cpu']) +CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json +all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) usage = sum(float(row['cpu']) for row in all_info) / len(all_info) return abs(usage - expect_cpu_usage) <= err_rate $$ LANGUAGE plpython3u; CREATE diff --git a/contrib/pax_storage/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql b/contrib/pax_storage/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql index 14220c38a42..a014108bb52 100644 --- a/contrib/pax_storage/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql +++ b/contrib/pax_storage/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql @@ -38,12 +38,11 @@ $$ LANGUAGE plpython3u; CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json - import functools all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) - usage = float(all_info[0]['cpu']) + usage = sum(float(row['cpu']) for row in all_info) / len(all_info) return abs(usage - expect_cpu_usage) <= err_rate $$ LANGUAGE plpython3u; diff --git a/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy.out b/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy.out index be070815b61..1f4d55e0b8a 100644 --- a/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy.out +++ b/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy.out @@ -1,3 +1,7 @@ +-- start_matchsubs +-- m/\(cluster.c:\d+\)/ +-- s/\(cluster.c:\d+\)/\(cluster.c:###\)/ +-- end_matchsubs -- ALTER TABLE ... SET DISTRIBUTED BY -- This is the main interface for system expansion \set DATA values(1, 2), (2, 3), (3, 4) @@ -171,7 +175,7 @@ ERROR: permission denied: "pg_class" is a system catalog create table atsdb (i int, j text) distributed by (j); insert into atsdb select i, i::text from generate_series(1, 10) i; alter table atsdb set with(appendonly = true); -ERROR: PAX not allow swap relation files for different AM (cluster.c:1535) +ERROR: PAX not allow swap relation files for different AM (cluster.c:###) select relname, segrelid != 0, reloptions from pg_class, pg_appendonly where pg_class.oid = 'atsdb'::regclass and relid = pg_class.oid; relname | ?column? | reloptions @@ -316,7 +320,7 @@ select * from distcheck where rel = 'atsdb'; alter table atsdb drop column n; alter table atsdb set with(appendonly = true, compresslevel = 3); -ERROR: PAX not allow swap relation files for different AM (cluster.c:1535) +ERROR: PAX not allow swap relation files for different AM (cluster.c:###) select relname, segrelid != 0, reloptions from pg_class, pg_appendonly where pg_class.oid = 'atsdb'::regclass and relid = pg_class.oid; relname | ?column? | reloptions diff --git a/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy_optimizer.out b/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy_optimizer.out index df30a5d8f05..0eafd5f8854 100644 --- a/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/alter_distribution_policy_optimizer.out @@ -1,3 +1,7 @@ +-- start_matchsubs +-- m/\(cluster.c:\d+\)/ +-- s/\(cluster.c:\d+\)/\(cluster.c:###\)/ +-- end_matchsubs -- ALTER TABLE ... SET DISTRIBUTED BY -- This is the main interface for system expansion \set DATA values(1, 2), (2, 3), (3, 4) @@ -171,7 +175,7 @@ ERROR: permission denied: "pg_class" is a system catalog create table atsdb (i int, j text) distributed by (j); insert into atsdb select i, i::text from generate_series(1, 10) i; alter table atsdb set with(appendonly = true); -ERROR: PAX not allow swap relation files for different AM (cluster.c:1535) +ERROR: PAX not allow swap relation files for different AM (cluster.c:###) select relname, segrelid != 0, reloptions from pg_class, pg_appendonly where pg_class.oid = 'atsdb'::regclass and relid = pg_class.oid; relname | ?column? | reloptions @@ -316,7 +320,7 @@ select * from distcheck where rel = 'atsdb'; alter table atsdb drop column n; alter table atsdb set with(appendonly = true, compresslevel = 3); -ERROR: PAX not allow swap relation files for different AM (cluster.c:1535) +ERROR: PAX not allow swap relation files for different AM (cluster.c:###) select relname, segrelid != 0, reloptions from pg_class, pg_appendonly where pg_class.oid = 'atsdb'::regclass and relid = pg_class.oid; relname | ?column? | reloptions diff --git a/contrib/pax_storage/src/test/regress/expected/rowtypes.out b/contrib/pax_storage/src/test/regress/expected/rowtypes.out index 9c92b2c403d..076f5cbb606 100644 --- a/contrib/pax_storage/src/test/regress/expected/rowtypes.out +++ b/contrib/pax_storage/src/test/regress/expected/rowtypes.out @@ -70,41 +70,36 @@ LINE 1: select '(Joe,Blow) /'::fullname; ^ DETAIL: Junk after right parenthesis. -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); +SELECT pg_input_is_valid('(1,2)', 'complex_t'); pg_input_is_valid ------------------- t (1 row) -SELECT pg_input_is_valid('(1,2', 'complex'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT pg_input_is_valid('(1,zed)', 'complex'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); message | detail | hint | sql_error_code -------------------------------------------------------+--------+------+---------------- invalid input syntax for type double precision: "zed" | | | 22P02 (1 row) -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); message | detail | hint | sql_error_code ---------------------------------------------------+--------+------+---------------- "1e400" is out of range for type double precision | | | 22003 (1 row) --- end_ignore create temp table quadtable(f1 int, q quad); insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); insert into quadtable values (2, ((null,4.4),(5.5,6.6))); diff --git a/contrib/pax_storage/src/test/regress/expected/rowtypes_optimizer.out b/contrib/pax_storage/src/test/regress/expected/rowtypes_optimizer.out index 32d93a68e4d..f0a84ed44d4 100644 --- a/contrib/pax_storage/src/test/regress/expected/rowtypes_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/rowtypes_optimizer.out @@ -70,41 +70,36 @@ LINE 1: select '(Joe,Blow) /'::fullname; ^ DETAIL: Junk after right parenthesis. -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); +SELECT pg_input_is_valid('(1,2)', 'complex_t'); pg_input_is_valid ------------------- t (1 row) -SELECT pg_input_is_valid('(1,2', 'complex'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT pg_input_is_valid('(1,zed)', 'complex'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); message | detail | hint | sql_error_code -------------------------------------------------------+--------+------+---------------- invalid input syntax for type double precision: "zed" | | | 22P02 (1 row) -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); message | detail | hint | sql_error_code ---------------------------------------------------+--------+------+---------------- "1e400" is out of range for type double precision | | | 22003 (1 row) --- end_ignore create temp table quadtable(f1 int, q quad); insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); insert into quadtable values (2, ((null,4.4),(5.5,6.6))); diff --git a/contrib/pax_storage/src/test/regress/sql/alter_distribution_policy.sql b/contrib/pax_storage/src/test/regress/sql/alter_distribution_policy.sql index feade3ed93d..6345ae987ec 100644 --- a/contrib/pax_storage/src/test/regress/sql/alter_distribution_policy.sql +++ b/contrib/pax_storage/src/test/regress/sql/alter_distribution_policy.sql @@ -1,3 +1,7 @@ +-- start_matchsubs +-- m/\(cluster.c:\d+\)/ +-- s/\(cluster.c:\d+\)/\(cluster.c:###\)/ +-- end_matchsubs -- ALTER TABLE ... SET DISTRIBUTED BY -- This is the main interface for system expansion \set DATA values(1, 2), (2, 3), (3, 4) diff --git a/contrib/pax_storage/src/test/regress/sql/rowtypes.sql b/contrib/pax_storage/src/test/regress/sql/rowtypes.sql index 7db4925dbe8..93319bf7e81 100644 --- a/contrib/pax_storage/src/test/regress/sql/rowtypes.sql +++ b/contrib/pax_storage/src/test/regress/sql/rowtypes.sql @@ -42,16 +42,11 @@ select ' (Joe,Blow) '::fullname; -- ok, extra whitespace select '(Joe,Blow) /'::fullname; -- bad -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); -SELECT pg_input_is_valid('(1,2', 'complex'); -SELECT pg_input_is_valid('(1,zed)', 'complex'); -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); --- end_ignore +SELECT pg_input_is_valid('(1,2)', 'complex_t'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); create temp table quadtable(f1 int, q quad); diff --git a/src/backend/access/aocs/aocsam_handler.c b/src/backend/access/aocs/aocsam_handler.c index 5cbf2015c64..4dc7d541c5f 100644 --- a/src/backend/access/aocs/aocsam_handler.c +++ b/src/backend/access/aocs/aocsam_handler.c @@ -1462,8 +1462,6 @@ aoco_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, int natts; Datum *values; bool *isnull; - TransactionId FreezeXid; - MultiXactId MultiXactCutoff; Tuplesortstate *tuplesort; PGRUsage ru0; @@ -1523,29 +1521,12 @@ aoco_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber); /* - * Compute sane values for FreezeXid and CutoffMulti with regular - * VACUUM machinery to avoidconfising existing CLUSTER code. + * AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't + * apply. Return Invalid values so that relfrozenxid and relminmxid + * remain unchanged after CLUSTER. */ - vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0, - &OldestXmin, &FreezeXid, NULL, &MultiXactCutoff, - NULL); - - /* - * FreezeXid will become the table's new relfrozenxid, and that mustn't go - * backwards, so take the max. - */ - if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid)) - FreezeXid = OldHeap->rd_rel->relfrozenxid; - - /* - * MultiXactCutoff, similarly, shouldn't go backwards either. - */ - if (MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid)) - MultiXactCutoff = OldHeap->rd_rel->relminmxid; - - /* return selected values to caller */ - *xid_cutoff = FreezeXid; - *multi_cutoff = MultiXactCutoff; + *xid_cutoff = InvalidTransactionId; + *multi_cutoff = InvalidMultiXactId; tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex, maintenance_work_mem, NULL, false); diff --git a/src/backend/access/appendonly/appendonlyam_handler.c b/src/backend/access/appendonly/appendonlyam_handler.c index cd37c0bbacd..cae12e110ff 100644 --- a/src/backend/access/appendonly/appendonlyam_handler.c +++ b/src/backend/access/appendonly/appendonlyam_handler.c @@ -1317,8 +1317,6 @@ appendonly_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, int natts; Datum *values; bool *isnull; - TransactionId FreezeXid; - MultiXactId MultiXactCutoff; Tuplesortstate *tuplesort; PGRUsage ru0; @@ -1380,29 +1378,12 @@ appendonly_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber); /* - * Compute sane values for FreezeXid and CutoffMulti with regular - * VACUUM machinery to avoidconfising existing CLUSTER code. + * AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't + * apply. Return Invalid values so that relfrozenxid and relminmxid + * remain unchanged after CLUSTER. */ - vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0, - &OldestXmin, &FreezeXid, NULL, &MultiXactCutoff, - NULL); - - /* - * FreezeXid will become the table's new relfrozenxid, and that mustn't go - * backwards, so take the max. - */ - if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid)) - FreezeXid = OldHeap->rd_rel->relfrozenxid; - - /* - * MultiXactCutoff, similarly, shouldn't go backwards either. - */ - if (MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid)) - MultiXactCutoff = OldHeap->rd_rel->relminmxid; - - /* return selected values to caller */ - *xid_cutoff = FreezeXid; - *multi_cutoff = MultiXactCutoff; + *xid_cutoff = InvalidTransactionId; + *multi_cutoff = InvalidMultiXactId; tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex, maintenance_work_mem, NULL, false); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index e31fe4cef8e..a3d2ad87bfb 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -1486,17 +1486,24 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, Assert(!TransactionIdIsValid(frozenXid) || TransactionIdIsNormal(frozenXid)); relform1->relfrozenxid = frozenXid; - Assert(MultiXactIdIsValid(cutoffMulti)); + Assert(!MultiXactIdIsValid(cutoffMulti) || + MultiXactIdPrecedesOrEquals(FirstMultiXactId, cutoffMulti)); relform1->relminmxid = cutoffMulti; } /* - * Cloudberry: append-optimized tables do not have a valid relfrozenxid. - * Overwrite the entry for both relations. + * Cloudberry: append-optimized tables do not have a valid relfrozenxid + * or relminmxid. Overwrite the entry for both relations. */ if (relform1->relkind != RELKIND_INDEX && IsAccessMethodAO(relform1->relam)) + { relform1->relfrozenxid = InvalidTransactionId; + relform1->relminmxid = InvalidMultiXactId; + } if (relform2->relkind != RELKIND_INDEX && IsAccessMethodAO(relform2->relam)) + { relform2->relfrozenxid = InvalidTransactionId; + relform2->relminmxid = InvalidMultiXactId; + } /* swap size statistics too, since new rel has freshly-updated stats */ if (swap_stats) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 80585a878a7..f4ba5615d5a 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -3914,202 +3914,3 @@ vac_cmp_itemptr(const void *left, const void *right) return 0; } - -void -vacuum_set_xid_limits(Relation rel, - int freeze_min_age, - int freeze_table_age, - int multixact_freeze_min_age, - int multixact_freeze_table_age, - TransactionId *oldestXmin, - TransactionId *freezeLimit, - TransactionId *xidFullScanLimit, - MultiXactId *multiXactCutoff, - MultiXactId *mxactFullScanLimit) -{ - int freezemin; - int mxid_freezemin; - int effective_multixact_freeze_max_age; - TransactionId limit; - TransactionId safeLimit; - MultiXactId oldestMxact; - MultiXactId mxactLimit; - MultiXactId safeMxactLimit; - - /* - * We can always ignore processes running lazy vacuum. This is because we - * use these values only for deciding which tuples we must keep in the - * tables. Since lazy vacuum doesn't write its XID anywhere (usually no - * XID assigned), it's safe to ignore it. In theory it could be - * problematic to ignore lazy vacuums in a full vacuum, but keep in mind - * that only one vacuum process can be working on a particular table at - * any time, and that each vacuum is always an independent transaction. - */ - *oldestXmin = GetOldestNonRemovableTransactionId(rel); - - if (OldSnapshotThresholdActive()) - { - TransactionId limit_xmin; - TimestampTz limit_ts; - - if (TransactionIdLimitedForOldSnapshots(*oldestXmin, rel, - &limit_xmin, &limit_ts)) - { - /* - * TODO: We should only set the threshold if we are pruning on the - * basis of the increased limits. Not as crucial here as it is - * for opportunistic pruning (which often happens at a much higher - * frequency), but would still be a significant improvement. - */ - SetOldSnapshotThresholdTimestamp(limit_ts, limit_xmin); - *oldestXmin = limit_xmin; - } - } - - Assert(TransactionIdIsNormal(*oldestXmin)); - - /* - * Determine the minimum freeze age to use: as specified by the caller, or - * vacuum_freeze_min_age, but in any case not more than half - * autovacuum_freeze_max_age, so that autovacuums to prevent XID - * wraparound won't occur too frequently. - */ - freezemin = freeze_min_age; - if (freezemin < 0) - freezemin = vacuum_freeze_min_age; - freezemin = Min(freezemin, autovacuum_freeze_max_age / 2); - Assert(freezemin >= 0); - - /* - * Compute the cutoff XID, being careful not to generate a "permanent" XID - */ - limit = *oldestXmin - freezemin; - if (!TransactionIdIsNormal(limit)) - limit = FirstNormalTransactionId; - - /* - * If oldestXmin is very far back (in practice, more than - * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum - * freeze age of zero. - */ - safeLimit = ReadNextTransactionId() - autovacuum_freeze_max_age; - if (!TransactionIdIsNormal(safeLimit)) - safeLimit = FirstNormalTransactionId; - - if (TransactionIdPrecedes(limit, safeLimit)) - { - ereport(WARNING, - (errmsg("oldest xmin is far in the past"), - errhint("Close open transactions soon to avoid wraparound problems.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); - limit = *oldestXmin; - } - - *freezeLimit = limit; - - /* - * Compute the multixact age for which freezing is urgent. This is - * normally autovacuum_multixact_freeze_max_age, but may be less if we are - * short of multixact member space. - */ - effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold(); - - /* - * Determine the minimum multixact freeze age to use: as specified by - * caller, or vacuum_multixact_freeze_min_age, but in any case not more - * than half effective_multixact_freeze_max_age, so that autovacuums to - * prevent MultiXact wraparound won't occur too frequently. - */ - mxid_freezemin = multixact_freeze_min_age; - if (mxid_freezemin < 0) - mxid_freezemin = vacuum_multixact_freeze_min_age; - mxid_freezemin = Min(mxid_freezemin, - effective_multixact_freeze_max_age / 2); - Assert(mxid_freezemin >= 0); - - /* compute the cutoff multi, being careful to generate a valid value */ - oldestMxact = GetOldestMultiXactId(); - mxactLimit = oldestMxact - mxid_freezemin; - if (mxactLimit < FirstMultiXactId) - mxactLimit = FirstMultiXactId; - - safeMxactLimit = - ReadNextMultiXactId() - effective_multixact_freeze_max_age; - if (safeMxactLimit < FirstMultiXactId) - safeMxactLimit = FirstMultiXactId; - - if (MultiXactIdPrecedes(mxactLimit, safeMxactLimit)) - { - ereport(WARNING, - (errmsg("oldest multixact is far in the past"), - errhint("Close open transactions with multixacts soon to avoid wraparound problems."))); - /* Use the safe limit, unless an older mxact is still running */ - if (MultiXactIdPrecedes(oldestMxact, safeMxactLimit)) - mxactLimit = oldestMxact; - else - mxactLimit = safeMxactLimit; - } - - *multiXactCutoff = mxactLimit; - - if (xidFullScanLimit != NULL) - { - int freezetable; - - Assert(mxactFullScanLimit != NULL); - - /* - * Determine the table freeze age to use: as specified by the caller, - * or vacuum_freeze_table_age, but in any case not more than - * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly - * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples - * before anti-wraparound autovacuum is launched. - */ - freezetable = freeze_table_age; - if (freezetable < 0) - freezetable = vacuum_freeze_table_age; - freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95); - Assert(freezetable >= 0); - - /* - * Compute XID limit causing a full-table vacuum, being careful not to - * generate a "permanent" XID. - */ - limit = ReadNextTransactionId() - freezetable; - if (!TransactionIdIsNormal(limit)) - limit = FirstNormalTransactionId; - - *xidFullScanLimit = limit; - - /* - * Similar to the above, determine the table freeze age to use for - * multixacts: as specified by the caller, or - * vacuum_multixact_freeze_table_age, but in any case not more than - * autovacuum_multixact_freeze_table_age * 0.95, so that if you have - * e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to - * freeze multixacts before anti-wraparound autovacuum is launched. - */ - freezetable = multixact_freeze_table_age; - if (freezetable < 0) - freezetable = vacuum_multixact_freeze_table_age; - freezetable = Min(freezetable, - effective_multixact_freeze_max_age * 0.95); - Assert(freezetable >= 0); - - /* - * Compute MultiXact limit causing a full-table vacuum, being careful - * to generate a valid MultiXact value. - */ - mxactLimit = ReadNextMultiXactId() - freezetable; - if (mxactLimit < FirstMultiXactId) - mxactLimit = FirstMultiXactId; - - *mxactFullScanLimit = mxactLimit; - } - else - { - Assert(mxactFullScanLimit == NULL); - } -} - - diff --git a/src/backend/commands/vacuum_ao.c b/src/backend/commands/vacuum_ao.c index dd0522f1986..075c73fb1c1 100644 --- a/src/backend/commands/vacuum_ao.c +++ b/src/backend/commands/vacuum_ao.c @@ -245,11 +245,6 @@ ao_vacuum_rel_post_cleanup(Relation onerel, VacuumParams *params, BufferAccessSt BlockNumber total_file_segs; int elevel; int options = params->options; - TransactionId OldestXmin; - TransactionId FreezeLimit; - MultiXactId MultiXactCutoff; - TransactionId xidFullScanLimit; - MultiXactId mxactFullScanLimit; if (options & VACOPT_VERBOSE) elevel = INFO; @@ -288,16 +283,11 @@ ao_vacuum_rel_post_cleanup(Relation onerel, VacuumParams *params, BufferAccessSt &relhasindex, &total_file_segs); - /* MERGE16_FIXME: How to set limits for ao */ - vacuum_set_xid_limits(onerel, - params->freeze_min_age, - params->freeze_table_age, - params->multixact_freeze_min_age, - params->multixact_freeze_table_age, - &OldestXmin, &FreezeLimit, &xidFullScanLimit, - &MultiXactCutoff, &mxactFullScanLimit); - - /* Causion: AO/AOCO use relallvisible to represent total segment file count */ + /* + * AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't + * apply. Pass InvalidTransactionId/InvalidMultiXactId to keep + * relfrozenxid and relminmxid unchanged. + */ vac_update_relstats(onerel, relpages, reltuples, @@ -305,8 +295,8 @@ ao_vacuum_rel_post_cleanup(Relation onerel, VacuumParams *params, BufferAccessSt Heap's 'all visible pages', use this field to represent AO/AOCO's total segment file count */ relhasindex, - FreezeLimit, - MultiXactCutoff, + InvalidTransactionId, + InvalidMultiXactId, NULL, NULL, false, diff --git a/src/backend/executor/nodePartitionSelector.c b/src/backend/executor/nodePartitionSelector.c index 7999a1a4d71..1a1e3affa85 100644 --- a/src/backend/executor/nodePartitionSelector.c +++ b/src/backend/executor/nodePartitionSelector.c @@ -101,7 +101,6 @@ ExecInitPartitionSelector(PartitionSelector *node, EState *estate, int eflags) outerPlanState(psstate) = ExecInitNode(outerPlan(node), estate, eflags); /* Create the working data structure for pruning. */ - /* MERGE16_FIXME: This use of ExecInitPartitionPruning may be incorrect */ psstate->prune_state = CreatePartitionPruneState(&psstate->ps, node->part_prune_info); return psstate; diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 76ce1e8fbea..6bb0f9a92a5 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -74,6 +74,7 @@ bool gp_enable_sort_limit = false; #define UNSAFE_NOTIN_DISTINCTON_CLAUSE (1 << 2) #define UNSAFE_NOTIN_PARTITIONBY_CLAUSE (1 << 3) #define UNSAFE_TYPE_MISMATCH (1 << 4) +#define UNSAFE_HAS_SUBPLAN (1 << 5) /* results of subquery_is_pushdown_safe */ typedef struct pushdown_safety_info @@ -4714,11 +4715,10 @@ check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo) continue; } - /* Refuse subplans */ + /* Refuse subplans (Cloudberry-specific, see UNSAFE_HAS_SUBPLAN) */ if (contain_subplans((Node *) tle->expr)) { - /*.MERGE16_FIXME: should we add a new unsafe type? */ - safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_NOTIN_PARTITIONBY_CLAUSE; + safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_HAS_SUBPLAN; continue; } } @@ -4896,7 +4896,8 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, { if (safetyInfo->unsafeFlags[var->varattno] & (UNSAFE_HAS_VOLATILE_FUNC | UNSAFE_HAS_SET_FUNC | - UNSAFE_NOTIN_DISTINCTON_CLAUSE | UNSAFE_TYPE_MISMATCH)) + UNSAFE_NOTIN_DISTINCTON_CLAUSE | UNSAFE_TYPE_MISMATCH | + UNSAFE_HAS_SUBPLAN)) { safe = PUSHDOWN_UNSAFE; break; diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index ebbecff523f..407bb90cec2 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -1576,10 +1576,14 @@ FileAccess(File file) static void ReportTemporaryFileUsage(const char *path, off_t size) { - /* MERGE16_FIXME: Now the pgstat has not worked, so disable the report first */ - return; - - pgstat_report_tempfile(size); + /* + * pgstat_report_tempfile() accesses shared memory via dshash, which + * may already be detached during process exit cleanup. Calling it + * from PathNameDeleteTemporaryDir's walkdir causes SIGSEGV in + * dshash_find(). Guard with IsUnderPostmaster and proc_exit_inprogress. + */ + if (!proc_exit_inprogress) + pgstat_report_tempfile(size); if (log_temp_files >= 0) { diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 0a390048819..8eba8a6d227 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1300,28 +1300,6 @@ exec_mpp_query(const char *query_string, elog(ERROR, "MPPEXEC: received non-DML Plan"); commandType = plan->commandType; - // MERGE16_FIXME: Check if wo should remove requiredPerms in Query -// if ( slice ) -// { -// /* Non root slices don't need update privileges. */ -// if (sliceTable->localSlice != slice->rootIndex) -// { -// ListCell *rtcell; -// RangeTblEntry *rte; -// RTEPermissionInfo *rte_permission; -// AclMode removeperms = ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_SELECT_FOR_UPDATE; -// -// /* Just reading, so don't check INS/DEL/UPD permissions. */ -// foreach(rtcell, plan->rtable) -// { -// rte = (RangeTblEntry *)lfirst(rtcell); -// if (rte->rtekind == RTE_RELATION && -// 0 != (rte->requiredPerms & removeperms)) -// rte->requiredPerms &= ~removeperms; -// } -// } -// } - if (log_statement != LOGSTMT_NONE) { /* diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c index a43dcb75398..beaeb669266 100644 --- a/src/backend/utils/activity/pgstat.c +++ b/src/backend/utils/activity/pgstat.c @@ -1301,8 +1301,7 @@ pgstat_get_kind_info(PgStat_Kind kind) void pgstat_assert_is_up(void) { - /* MERGE16_FIXME: Now the pgstat has not worked, so disable the assert first */ -// Assert(pgstat_is_initialized && !pgstat_is_shutdown); + Assert(pgstat_is_initialized && !pgstat_is_shutdown); } #endif diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c index 3250d285e02..f0fa5838e66 100644 --- a/src/backend/utils/adt/rowtypes.c +++ b/src/backend/utils/adt/rowtypes.c @@ -154,7 +154,6 @@ record_in(PG_FUNCTION_ARGS) ptr++; if (*ptr++ != '(') { - ReleaseTupleDesc(tupdesc); errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("malformed record literal: \"%s\"", string), @@ -186,7 +185,6 @@ record_in(PG_FUNCTION_ARGS) ptr++; else { - ReleaseTupleDesc(tupdesc); /* *ptr must be ')' */ errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -214,7 +212,6 @@ record_in(PG_FUNCTION_ARGS) if (ch == '\0') { - ReleaseTupleDesc(tupdesc); errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("malformed record literal: \"%s\"", @@ -226,7 +223,6 @@ record_in(PG_FUNCTION_ARGS) { if (*ptr == '\0') { - ReleaseTupleDesc(tupdesc); errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("malformed record literal: \"%s\"", @@ -285,7 +281,6 @@ record_in(PG_FUNCTION_ARGS) if (*ptr++ != ')') { - ReleaseTupleDesc(tupdesc); errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("malformed record literal: \"%s\"", string), @@ -297,7 +292,6 @@ record_in(PG_FUNCTION_ARGS) ptr++; if (*ptr) { - ReleaseTupleDesc(tupdesc); errsave(escontext, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("malformed record literal: \"%s\"", string), diff --git a/src/bin/pg_basebackup/bbstreamer_file.c b/src/bin/pg_basebackup/bbstreamer_file.c index 504225f0959..6101cc2ab97 100644 --- a/src/bin/pg_basebackup/bbstreamer_file.c +++ b/src/bin/pg_basebackup/bbstreamer_file.c @@ -327,7 +327,6 @@ should_allow_existing_directory(const char *pathname) static void extract_directory(const char *filename, mode_t mode) { - /* MERGE16_FIXME: We should test forceoverwrite here ? */ if (pg_check_dir(filename) != 0) { /* diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index d700f4a72cc..431cd7221a8 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -491,15 +491,6 @@ extern Size vac_max_items_to_alloc_size(int max_items); /* In postmaster/autovacuum.c */ extern void AutoVacuumUpdateCostLimit(void); extern void VacuumUpdateCosts(void); -extern void vacuum_set_xid_limits(Relation rel, - int freeze_min_age, int freeze_table_age, - int multixact_freeze_min_age, - int multixact_freeze_table_age, - TransactionId *oldestXmin, - TransactionId *freezeLimit, - TransactionId *xidFullScanLimit, - MultiXactId *multiXactCutoff, - MultiXactId *mxactFullScanLimit); /* in commands/vacuumparallel.c */ extern ParallelVacuumState *parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes, int nrequested_workers, diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h index 22c4fc9a5e6..91bc97db8c6 100644 --- a/src/include/executor/execPartition.h +++ b/src/include/executor/execPartition.h @@ -130,14 +130,10 @@ extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate, EState *estate); extern void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute); -extern PartitionPruneState *ExecCreatePartitionPruneState(PlanState *planstate, - PartitionPruneInfo *partitionpruneinfo); extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune, EState *estate, int nplans, List *join_prune_paramids); -extern Bitmapset *ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, - int nsubplans); extern int get_partition_for_tuple(PartitionKey key, PartitionDesc partdesc, Datum *values, bool *isnull); diff --git a/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out b/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out index 2e7b32f1d74..44969ba7eea 100644 --- a/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out +++ b/src/test/isolation2/expected/resgroup/resgroup_cpu_max_percent.out @@ -33,8 +33,8 @@ CREATE -- verify_cpu_usage: calculate each QE's average cpu usage using all the data in -- the table cpu_usage_sample. And compare the average value to the expected value. -- return true if the practical value is close to the expected value. -CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json import functools -all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) usage = float(all_info[0]['cpu']) +CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json +all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) usage = sum(float(row['cpu']) for row in all_info) / len(all_info) return abs(usage - expect_cpu_usage) <= err_rate $$ LANGUAGE plpython3u; CREATE diff --git a/src/test/isolation2/expected/vacuum_progress_column.out b/src/test/isolation2/expected/vacuum_progress_column.out index fcc983f1e43..12a3bceb78f 100644 --- a/src/test/isolation2/expected/vacuum_progress_column.out +++ b/src/test/isolation2/expected/vacuum_progress_column.out @@ -339,15 +339,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he -------------------------- Success: (1 row) --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -CREATE OR REPLACE FUNCTION wait_for_mirror_down(content_id int) RETURNS bool AS $$ declare /* in func */ retries int; /* in func */ begin /* in func */ retries := 60; /* in func */ loop /* in func */ perform gp_request_fts_probe_scan(); /* in func */ if (select status = 'd' from gp_segment_configuration where content = content_id and role = 'm') then /* in func */ return true; /* in func */ end if; /* in func */ if retries <= 0 then /* in func */ return false; /* in func */ end if; /* in func */ perform pg_sleep(1); /* in func */ retries := retries - 1; /* in func */ end loop; /* in func */ end; /* in func */ $$ language plpgsql; -CREATE -2: SELECT wait_for_mirror_down(1); - wait_for_mirror_down ----------------------- - t -(1 row) -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point @@ -398,14 +389,14 @@ CREATE select gp_segment_id, relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, index_vacuum_count, max_dead_tuples, num_dead_tuples from gp_stat_progress_vacuum where gp_segment_id > -1; gp_segment_id | relname | phase | heap_blks_total | heap_blks_scanned | heap_blks_vacuumed | index_vacuum_count | max_dead_tuples | num_dead_tuples ---------------+---------------------------+-------------------------------+-----------------+-------------------+--------------------+--------------------+-----------------+----------------- - 2 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 9 | 2 | 0 | 0 - 0 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 9 | 2 | 0 | 0 - 1 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 9 | 2 | 0 | 0 + 2 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 0 | 0 | 0 | 0 + 0 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 0 | 0 | 0 | 0 + 1 | vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 0 | 0 | 0 | 0 (3 rows) select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, index_vacuum_count, max_dead_tuples, num_dead_tuples from gp_stat_progress_vacuum_summary; relname | phase | heap_blks_total | heap_blks_scanned | heap_blks_vacuumed | index_vacuum_count | max_dead_tuples | num_dead_tuples ---------------------------+-------------------------------+-----------------+-------------------+--------------------+--------------------+-----------------+----------------- - vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 27 | 6 | 0 | 0 + vacuum_progress_ao_column | append-optimized post-cleanup | 0 | 0 | 0 | 0 | 0 | 0 (1 row) 2: SELECT gp_inject_fault('vacuum_ao_post_cleanup_end', 'reset', dbid) FROM gp_segment_configuration WHERE content > -1 AND role = 'p'; diff --git a/src/test/isolation2/expected/vacuum_progress_row.out b/src/test/isolation2/expected/vacuum_progress_row.out index 29809709eab..ef39d8edaf3 100644 --- a/src/test/isolation2/expected/vacuum_progress_row.out +++ b/src/test/isolation2/expected/vacuum_progress_row.out @@ -293,8 +293,6 @@ SELECT n_live_tup, n_dead_tup, last_vacuum is not null as has_last_vacuum, vacuu -- phase (at injecting point vacuum_ao_post_cleanup_end), which is different from above case -- in which vacuum worker isn't changed. -CREATE OR REPLACE FUNCTION wait_for_mirror_down(content_id int) RETURNS bool AS $$ declare /* in func */ retries int; /* in func */ begin /* in func */ retries := 60; /* in func */ loop /* in func */ perform gp_request_fts_probe_scan(); /* in func */ if (select status = 'd' from gp_segment_configuration where content = content_id and role = 'm') then /* in func */ return true; /* in func */ end if; /* in func */ if retries <= 0 then /* in func */ return false; /* in func */ end if; /* in func */ perform pg_sleep(1); /* in func */ retries := retries - 1; /* in func */ end loop; /* in func */ end; /* in func */ $$ language plpgsql; -CREATE DROP TABLE IF EXISTS vacuum_progress_ao_row; DROP CREATE TABLE vacuum_progress_ao_row(i int, j int); @@ -395,13 +393,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he -------------------------- Success: (1 row) --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -2: SELECT wait_for_mirror_down(1); - wait_for_mirror_down ----------------------- - t -(1 row) -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point @@ -606,13 +597,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he -------------------------- Success: (1 row) --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -2: SELECT wait_for_mirror_down(1); - wait_for_mirror_down ----------------------- - t -(1 row) -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point diff --git a/src/test/isolation2/isolation2_schedule b/src/test/isolation2/isolation2_schedule index 7e7e4220d12..82d23731fb6 100644 --- a/src/test/isolation2/isolation2_schedule +++ b/src/test/isolation2/isolation2_schedule @@ -253,8 +253,7 @@ test: segwalrep/dtm_recovery_on_standby test: segwalrep/commit_blocking_on_standby test: segwalrep/dtx_recovery_wait_lsn -# MERGE16_FIXME: enable this case latter -# test: segwalrep/select_throttle +test: segwalrep/select_throttle test: segwalrep/startup_rename_prepared_xlog test: fts_manual_probe test: fts_session_reset diff --git a/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql b/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql index c7dfc9f60b0..89fa523cc88 100644 --- a/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql +++ b/src/test/isolation2/sql/resgroup/resgroup_cpu_max_percent.sql @@ -38,12 +38,11 @@ $$ LANGUAGE plpython3u; CREATE OR REPLACE FUNCTION verify_cpu_usage(groupname TEXT, expect_cpu_usage INT, err_rate INT) RETURNS BOOL AS $$ import json - import functools all_info = plpy.execute(''' SELECT sample::json->'{name}' AS cpu FROM cpu_usage_samples '''.format(name=groupname)) - usage = float(all_info[0]['cpu']) + usage = sum(float(row['cpu']) for row in all_info) / len(all_info) return abs(usage - expect_cpu_usage) <= err_rate $$ LANGUAGE plpython3u; diff --git a/src/test/isolation2/sql/vacuum_progress_column.sql b/src/test/isolation2/sql/vacuum_progress_column.sql index 519c3e37200..60250368b46 100644 --- a/src/test/isolation2/sql/vacuum_progress_column.sql +++ b/src/test/isolation2/sql/vacuum_progress_column.sql @@ -141,27 +141,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he 2: SELECT gp_inject_fault('vacuum_worker_changed', 'suspend', dbid) FROM gp_segment_configuration WHERE content > -1 AND role = 'p'; -- resume walsender and let it exit so that mirror stop can be detected 2: SELECT gp_inject_fault_infinite('wal_sender_loop', 'reset', dbid) FROM gp_segment_configuration WHERE role = 'p' and content = 1; --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -CREATE OR REPLACE FUNCTION wait_for_mirror_down(content_id int) RETURNS bool AS $$ -declare /* in func */ - retries int; /* in func */ -begin /* in func */ - retries := 60; /* in func */ - loop /* in func */ - perform gp_request_fts_probe_scan(); /* in func */ - if (select status = 'd' from gp_segment_configuration where content = content_id and role = 'm') then /* in func */ - return true; /* in func */ - end if; /* in func */ - if retries <= 0 then /* in func */ - return false; /* in func */ - end if; /* in func */ - perform pg_sleep(1); /* in func */ - retries := retries - 1; /* in func */ - end loop; /* in func */ -end; /* in func */ -$$ language plpgsql; -2: SELECT wait_for_mirror_down(1); -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point diff --git a/src/test/isolation2/sql/vacuum_progress_row.sql b/src/test/isolation2/sql/vacuum_progress_row.sql index 125368df72b..c832a1fd0df 100644 --- a/src/test/isolation2/sql/vacuum_progress_row.sql +++ b/src/test/isolation2/sql/vacuum_progress_row.sql @@ -107,24 +107,6 @@ SELECT n_live_tup, n_dead_tup, last_vacuum is not null as has_last_vacuum, vacuu -- phase (at injecting point vacuum_ao_post_cleanup_end), which is different from above case -- in which vacuum worker isn't changed. -CREATE OR REPLACE FUNCTION wait_for_mirror_down(content_id int) RETURNS bool AS $$ -declare /* in func */ - retries int; /* in func */ -begin /* in func */ - retries := 60; /* in func */ - loop /* in func */ - perform gp_request_fts_probe_scan(); /* in func */ - if (select status = 'd' from gp_segment_configuration where content = content_id and role = 'm') then /* in func */ - return true; /* in func */ - end if; /* in func */ - if retries <= 0 then /* in func */ - return false; /* in func */ - end if; /* in func */ - perform pg_sleep(1); /* in func */ - retries := retries - 1; /* in func */ - end loop; /* in func */ -end; /* in func */ -$$ language plpgsql; DROP TABLE IF EXISTS vacuum_progress_ao_row; CREATE TABLE vacuum_progress_ao_row(i int, j int); CREATE INDEX on vacuum_progress_ao_row(i); @@ -164,9 +146,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he 2: SELECT gp_inject_fault('vacuum_worker_changed', 'suspend', dbid) FROM gp_segment_configuration WHERE content > -1 AND role = 'p'; -- resume walsender and let it exit so that mirror stop can be detected 2: SELECT gp_inject_fault_infinite('wal_sender_loop', 'reset', dbid) FROM gp_segment_configuration WHERE role = 'p' and content = 1; --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -2: SELECT wait_for_mirror_down(1); -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point @@ -241,9 +220,6 @@ select relid::regclass as relname, phase, heap_blks_total, heap_blks_scanned, he 2: SELECT gp_inject_fault('vacuum_worker_changed', 'suspend', dbid) FROM gp_segment_configuration WHERE content > -1 AND role = 'p'; -- resume walsender and let it exit so that mirror stop can be detected 2: SELECT gp_inject_fault_infinite('wal_sender_loop', 'reset', dbid) FROM gp_segment_configuration WHERE role = 'p' and content = 1; --- Trigger FTS probe repeatedly until mirror is marked as down, so that --- FTS version change propagates to QD and gang gets reset. -2: SELECT wait_for_mirror_down(1); -- Ensure we enter into the target logic which stops cumulative data but -- initializes a new vacrelstats at the beginning of post-cleanup phase. -- Also all segments should reach to the same "vacuum_worker_changed" point diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index ecd4ee0deb3..d86bab812db 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -70,41 +70,36 @@ LINE 1: select '(Joe,Blow) /'::fullname; ^ DETAIL: Junk after right parenthesis. -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); +SELECT pg_input_is_valid('(1,2)', 'complex_t'); pg_input_is_valid ------------------- t (1 row) -SELECT pg_input_is_valid('(1,2', 'complex'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT pg_input_is_valid('(1,zed)', 'complex'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); message | detail | hint | sql_error_code -------------------------------------------------------+--------+------+---------------- invalid input syntax for type double precision: "zed" | | | 22P02 (1 row) -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); message | detail | hint | sql_error_code ---------------------------------------------------+--------+------+---------------- "1e400" is out of range for type double precision | | | 22003 (1 row) --- end_ignore create temp table quadtable(f1 int, q quad); insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); insert into quadtable values (2, ((null,4.4),(5.5,6.6))); diff --git a/src/test/regress/expected/rowtypes_optimizer.out b/src/test/regress/expected/rowtypes_optimizer.out index e937a160d96..6edc5cbda2a 100644 --- a/src/test/regress/expected/rowtypes_optimizer.out +++ b/src/test/regress/expected/rowtypes_optimizer.out @@ -70,41 +70,36 @@ LINE 1: select '(Joe,Blow) /'::fullname; ^ DETAIL: Junk after right parenthesis. -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); +SELECT pg_input_is_valid('(1,2)', 'complex_t'); pg_input_is_valid ------------------- t (1 row) -SELECT pg_input_is_valid('(1,2', 'complex'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT pg_input_is_valid('(1,zed)', 'complex'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); pg_input_is_valid ------------------- f (1 row) -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); message | detail | hint | sql_error_code -------------------------------------------------------+--------+------+---------------- invalid input syntax for type double precision: "zed" | | | 22P02 (1 row) -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); message | detail | hint | sql_error_code ---------------------------------------------------+--------+------+---------------- "1e400" is out of range for type double precision | | | 22003 (1 row) --- end_ignore create temp table quadtable(f1 int, q quad); insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); insert into quadtable values (2, ((null,4.4),(5.5,6.6))); diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index 8175022c3f4..655fe4c0349 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -42,16 +42,11 @@ select ' (Joe,Blow) '::fullname; -- ok, extra whitespace select '(Joe,Blow) /'::fullname; -- bad -- test non-error-throwing API --- MERGE16_FIXME: --- The greenplum implement complex type by itself, postgres implement --- it now. should we use the complex type implemented by postgres. --- start_ignore -SELECT pg_input_is_valid('(1,2)', 'complex'); -SELECT pg_input_is_valid('(1,2', 'complex'); -SELECT pg_input_is_valid('(1,zed)', 'complex'); -SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); -SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); --- end_ignore +SELECT pg_input_is_valid('(1,2)', 'complex_t'); +SELECT pg_input_is_valid('(1,2', 'complex_t'); +SELECT pg_input_is_valid('(1,zed)', 'complex_t'); +SELECT * FROM pg_input_error_info('(1,zed)', 'complex_t'); +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex_t'); create temp table quadtable(f1 int, q quad); diff --git a/src/test/singlenode_isolation2/expected/prevent_ao_wal.out b/src/test/singlenode_isolation2/expected/prevent_ao_wal.out index fb5f556ce91..be069bcee39 100644 --- a/src/test/singlenode_isolation2/expected/prevent_ao_wal.out +++ b/src/test/singlenode_isolation2/expected/prevent_ao_wal.out @@ -15,7 +15,7 @@ GP_IGNORE: formatted by atmsort.pm -- start_matchignore --- m/pg_waldump: fatal: error in WAL record at */ +-- m/pg_waldump: (fatal|error): .*/ -- m/.*The 'DISTRIBUTED BY' clause determines the distribution of data*/ -- m/.*Table doesn't have 'DISTRIBUTED BY' clause*/ -- end_matchignore @@ -64,31 +64,28 @@ VACUUM -1Uq: ... -- Validate wal records --- MERGE16_FIXME: this should throw a 'pg_waldump: error: error in WAL record at 0/40247EF8: invalid record length at 0/40247F28: expected at least 24, got 0' ERROR, fix it later --- start_ignore ! last_wal_file=$(psql -At -c "SELECT pg_walfile_name(pg_current_wal_lsn())" postgres) && pg_waldump ${last_wal_file} -p ${COORDINATOR_DATA_DIRECTORY}/pg_wal -r appendonly; -rmgr: Appendonly len (rec/tot): 186/ 186, tx: 12661, lsn: 0/F8000178, prev 0/F8000128, desc: APPENDONLY_INSERT insert: rel 1663/221728/180472 seg/offset:0/0 len:136 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12662, lsn: 0/F8000400, prev 0/F80003C0, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:128/0 len:0 -rmgr: Appendonly len (rec/tot): 130/ 130, tx: 12662, lsn: 0/F8000490, prev 0/F8000440, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:0/0 len:80 -rmgr: Appendonly len (rec/tot): 130/ 130, tx: 12662, lsn: 0/F8000520, prev 0/F8000490, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:128/0 len:80 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8000840, prev 0/F8000810, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180472 seg/offset:0/136 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12664, lsn: 0/F8000A18, prev 0/F80009D8, desc: APPENDONLY_INSERT insert: rel 1663/221728/180472 seg/offset:1/0 len:0 -rmgr: Appendonly len (rec/tot): 138/ 138, tx: 12664, lsn: 0/F8000B38, prev 0/F8000AF8, desc: APPENDONLY_INSERT insert: rel 1663/221728/180472 seg/offset:1/0 len:88 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12665, lsn: 0/F8000C98, prev 0/F8000C68, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180472 seg/offset:0/0 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F80412F8, prev 0/F80412C8, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:0/80 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8041338, prev 0/F80412F8, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:128/80 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8307118, prev 0/F83070E8, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180472 seg/offset:1/88 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8307150, prev 0/F8307118, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180472 seg/offset:0/0 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8307208, prev 0/F83071D8, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:0/80 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 0, lsn: 0/F8307248, prev 0/F8307208, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:128/80 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12673, lsn: 0/F8307440, prev 0/F8307400, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:1/0 len:0 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12673, lsn: 0/F8307480, prev 0/F8307440, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:129/0 len:0 -rmgr: Appendonly len (rec/tot): 114/ 114, tx: 12673, lsn: 0/F83075A0, prev 0/F8307560, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:1/0 len:64 -rmgr: Appendonly len (rec/tot): 114/ 114, tx: 12673, lsn: 0/F8307620, prev 0/F83075A0, desc: APPENDONLY_INSERT insert: rel 1663/221728/180476 seg/offset:129/0 len:64 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12674, lsn: 0/F8307780, prev 0/F8307750, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:0/0 -rmgr: Appendonly len (rec/tot): 50/ 50, tx: 12674, lsn: 0/F83077C0, prev 0/F8307780, desc: APPENDONLY_TRUNCATE truncate: rel 1663/221728/180476 seg/offset:128/0 +rmgr: Appendonly len (rec/tot): 186/ 186, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:0/0 len:136 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:128/0 len:0 +rmgr: Appendonly len (rec/tot): 130/ 130, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:0/0 len:80 +rmgr: Appendonly len (rec/tot): 130/ 130, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:128/0 len:80 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/136 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:1/0 len:0 +rmgr: Appendonly len (rec/tot): 138/ 138, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:1/0 len:88 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/0 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/80 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:128/80 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:1/88 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/0 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/80 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:128/80 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:1/0 len:0 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:129/0 len:0 +rmgr: Appendonly len (rec/tot): 114/ 114, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:1/0 len:64 +rmgr: Appendonly len (rec/tot): 114/ 114, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_INSERT insert: rel ####/######/###### seg/offset:129/0 len:64 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:0/0 +rmgr: Appendonly len (rec/tot): 50/ 50, tx: ##, lsn: #/########, prev #/########, desc: APPENDONLY_TRUNCATE truncate: rel ####/######/###### seg/offset:128/0 --- end_ignore -- *********** Set wal_level=minimal ************** !\retcode gpconfig -c wal_level -v minimal --masteronly; @@ -124,10 +121,8 @@ DELETE 5 VACUUM -- Validate wal records --- start_ignore ! last_wal_file=$(psql -At -c "SELECT pg_walfile_name(pg_current_wal_lsn())" postgres) && pg_waldump ${last_wal_file} -p ${COORDINATOR_DATA_DIRECTORY}/pg_wal -r appendonly; --- end_ignore -1U: DROP TABLE ao_foo; DROP diff --git a/src/test/singlenode_isolation2/input/workfile_mgr_test.source b/src/test/singlenode_isolation2/input/workfile_mgr_test.source index 30f03315d7e..f5e189e694b 100644 --- a/src/test/singlenode_isolation2/input/workfile_mgr_test.source +++ b/src/test/singlenode_isolation2/input/workfile_mgr_test.source @@ -57,7 +57,7 @@ language plpgsql volatile execute on all segments; -- start_ignore !\retcode gpconfig -c gp_workfile_max_entries -v 32 --skipvalidation; -!\retcode gpstop -ari; +!\retcode gpstop -arf; -- end_ignore -- setup for workfile made in temp tablespace test @@ -80,7 +80,7 @@ language plpgsql volatile execute on all segments; -- start_ignore !\retcode gpconfig -r gp_workfile_max_entries --skipvalidation; -!\retcode gpstop -ari; +!\retcode gpstop -arf; -- end_ignore -- test workset cleanup diff --git a/src/test/singlenode_isolation2/isolation2_schedule b/src/test/singlenode_isolation2/isolation2_schedule index adf4e6c0ede..7e5266d1c84 100644 --- a/src/test/singlenode_isolation2/isolation2_schedule +++ b/src/test/singlenode_isolation2/isolation2_schedule @@ -211,8 +211,7 @@ test: uao/bitmapindex_rescan_column # test: add_column_after_vacuum_skip_drop_column # test: vacuum_after_vacuum_skip_drop_column # test workfile_mgr -# MERGE16_FIXME: enable workfile_mgr_test later -#test: workfile_mgr_test +test: workfile_mgr_test # test: pg_basebackup # test: pg_basebackup_with_tablespaces test: enable_autovacuum diff --git a/src/test/singlenode_isolation2/output/workfile_mgr_test.source b/src/test/singlenode_isolation2/output/workfile_mgr_test.source index a6821ecc38b..5fcbd06dde4 100644 --- a/src/test/singlenode_isolation2/output/workfile_mgr_test.source +++ b/src/test/singlenode_isolation2/output/workfile_mgr_test.source @@ -30,7 +30,7 @@ CREATE -- end_ignore (exited with code 0) -!\retcode gpstop -ari; +!\retcode gpstop -arf; -- start_ignore 20200923:12:05:57:014232 gpstop:mdw:gpadmin-[INFO]:-Starting gpstop with args: -ari 20200923:12:05:57:014232 gpstop:mdw:gpadmin-[INFO]:-Gathering information and validating the environment... @@ -122,7 +122,7 @@ DROP -- end_ignore (exited with code 0) -!\retcode gpstop -ari; +!\retcode gpstop -arf; -- start_ignore 20230630:09:01:15:025313 gpstop:merge:gpadmin-[INFO]:-Starting gpstop with args: -ari 20230630:09:01:15:025313 gpstop:merge:gpadmin-[INFO]:-Gathering information and validating the environment... diff --git a/src/test/singlenode_isolation2/sql/prevent_ao_wal.sql b/src/test/singlenode_isolation2/sql/prevent_ao_wal.sql index 06b64591658..c9a32051f18 100644 --- a/src/test/singlenode_isolation2/sql/prevent_ao_wal.sql +++ b/src/test/singlenode_isolation2/sql/prevent_ao_wal.sql @@ -14,7 +14,7 @@ -- validate WAL records on the coordinator. -- start_matchignore --- m/pg_waldump: fatal: error in WAL record at */ +-- m/pg_waldump: (fatal|error): .*/ -- m/.*The 'DISTRIBUTED BY' clause determines the distribution of data*/ -- m/.*Table doesn't have 'DISTRIBUTED BY' clause*/ -- end_matchignore @@ -49,10 +49,7 @@ -1Uq: -- Validate wal records --- MERGE16_FIXME: this should throw a 'pg_waldump: error: error in WAL record at 0/40247EF8: invalid record length at 0/40247F28: expected at least 24, got 0' ERROR, fix it later --- start_ignore ! last_wal_file=$(psql -At -c "SELECT pg_walfile_name(pg_current_wal_lsn())" postgres) && pg_waldump ${last_wal_file} -p ${COORDINATOR_DATA_DIRECTORY}/pg_wal -r appendonly; --- end_ignore -- *********** Set wal_level=minimal ************** !\retcode gpconfig -c wal_level -v minimal --masteronly; @@ -75,9 +72,7 @@ -1U: VACUUM; -- Validate wal records --- start_ignore ! last_wal_file=$(psql -At -c "SELECT pg_walfile_name(pg_current_wal_lsn())" postgres) && pg_waldump ${last_wal_file} -p ${COORDINATOR_DATA_DIRECTORY}/pg_wal -r appendonly; --- end_ignore -1U: DROP TABLE ao_foo; -1U: DROP TABLE aoco_foo;