diff --git a/Cluster.pm b/Cluster.pm index ea7860f695..fccda7aa1b 100644 --- a/Cluster.pm +++ b/Cluster.pm @@ -3,13 +3,31 @@ package Cluster; use strict; use warnings; -use PostgresNode; -use TestLib; use Test::More; use Cwd; use IPC::Run; use Socket; +our $pg_15_modules; + +BEGIN +{ + $pg_15_modules = eval + { + require PostgreSQL::Test::Cluster; + require PostgreSQL::Test::Utils; + return 1; + }; + + unless (defined $pg_15_modules) + { + $pg_15_modules = 0; + + require PostgresNode; + require TestLib; + } +} + our $last_port_assigned; our $mm_listen_address = '127.0.0.1'; @@ -38,10 +56,24 @@ sub mm_get_free_port # Check first that candidate port number is not included in # the list of already-registered nodes. $found = 1; - foreach my $node (@PostgresNode::all_nodes) + eval { - $found = 0 if ($node->port == $port); - } + if ($pg_15_modules) + { + foreach my $node (@PostgreSQL::Test::Cluster::all_nodes) + { + $found = 0 if ($node->port == $port); + } + } + else + { + foreach my $node (@PostgresNode::all_nodes) + { + $found = 0 if ($node->port == $port); + } + } + }; + # Check to see if anything else is listening on this TCP port. # Seek a port available for all possible listen_addresses values, @@ -57,15 +89,33 @@ sub mm_get_free_port # 0.0.0.0 is unnecessary on non-Windows systems. if ($found == 1) { - foreach my $addr (qw(127.0.0.1), - $PostgresNode::use_tcp && ($^O eq "linux" || $windows_os) ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ()) + eval { - if (!PostgresNode::can_bind($addr, $port)) + if ($pg_15_modules) { - $found = 0; - last; + foreach my $addr (qw(127.0.0.1), + $PostgreSQL::Test::Cluster::use_tcp && ($^O eq "linux" || $PostgreSQL::Test::Utils::windows_os) ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ()) + { + if (!PostgreSQL::Test::Cluster::can_bind($addr, $port)) + { + $found = 0; + last; + } + } } - } + else + { + foreach my $addr (qw(127.0.0.1), + $PostgresNode::use_tcp && ($^O eq "linux" || $TestLib::windows_os) ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ()) + { + if (!PostgresNode::can_bind($addr, $port)) + { + $found = 0; + last; + } + } + } + }; } } @@ -80,21 +130,41 @@ sub mm_get_free_port sub new { my ($class, $n_nodes, $referee) = @_; + my @nodes; + my $self; # ask PostgresNode to use tcp and listen on mm_listen_address - $PostgresNode::use_tcp = 1; - $PostgresNode::test_pghost = $mm_listen_address; - - my @nodes = map { get_new_node("node$_", ('port' => mm_get_free_port())) } (1..$n_nodes); - - my $self = { - nodes => \@nodes, - recv_timeout => 6 - }; - if (defined $referee && $referee) + eval { - $self->{referee} = get_new_node("referee", ( 'port' => mm_get_free_port() )); - } + if ($pg_15_modules) + { + $PostgreSQL::Test::Cluster::use_tcp = 1; + $PostgreSQL::Test::Cluster::test_pghost = $mm_listen_address; + @nodes = map { PostgreSQL::Test::Cluster->new("node$_", ('port' => mm_get_free_port())) } (1..$n_nodes); + $self = { + nodes => \@nodes, + recv_timeout => 6 + }; + if (defined $referee && $referee) + { + $self->{referee} = PostgreSQL::Test::Cluster->new("referee", ( 'port' => mm_get_free_port() )); + } + } + else + { + $PostgresNode::use_tcp = 1; + $PostgresNode::test_pghost = $mm_listen_address; + @nodes = map { PostgresNode::get_new_node("node$_", ('port' => mm_get_free_port())) } (1..$n_nodes); + $self = { + nodes => \@nodes, + recv_timeout => 6 + }; + if (defined $referee && $referee) + { + $self->{referee} = PostgresNode::get_new_node("referee", ( 'port' => mm_get_free_port() )); + } + } + }; bless $self, $class; return $self; @@ -106,7 +176,17 @@ sub init my $nodes = $self->{nodes}; # use port range different to ordinary TAP tests - $PostgresNode::last_port_assigned = int(rand() * 16384) + 32767; + eval + { + if ($pg_15_modules) + { + $PostgreSQL::Test::Cluster::last_port_assigned = int(rand() * 16384) + 32767; + } + else + { + $PostgresNode::last_port_assigned = int(rand() * 16384) + 32767; + } + }; if (defined $self->{referee}) { @@ -122,7 +202,19 @@ sub init # everywhere but on arm (which is the only live arch which might be strict # here) my $binary_basetypes = 0; - if (!$TestLib::windows_os) + my $is_windows_os; + eval + { + if ($pg_15_modules) + { + $is_windows_os = $PostgreSQL::Test::Utils::windows_os; + } + else + { + $is_windows_os = $TestLib::windows_os; + } + }; + if (!$is_windows_os) { my $uname_arch = `uname -m`; if ($? != 0) { @@ -182,14 +274,52 @@ sub init # multimaster.CoordinatorTrace_log_level = LOG + # multimaster.DmqStateIntermediate_log_level = LOG + # multimaster.DmqStateFinal_log_level = LOG + # multimaster.DmqTraceOutgoing_log_level = LOG + # multimaster.DmqTraceIncoming_log_level = LOG + # multimaster.DmqTraceShmMq_log_level = LOG + # multimaster.DmqPqTiming_log_level = LOG + + # multimaster.ResolverState_log_level = LOG + # multimaster.ResolverTx_log_level = LOG + # multimaster.ResolverTasks_log_level = LOG + + # multimaster.StatusRequest_log_level = LOG + + # multimaster.BgwPoolEvent_log_level = LOG # multimaster.BgwPoolEventDebug_log_level = LOG + # multimaster.DeadlockCheck_log_level = LOG + # multimaster.DeadlockUpdate_log_level = LOG + # multimaster.DeadlockSerialize_log_level = LOG + + # multimaster.DDLStmtOutgoing_log_level = LOG + # multimaster.DDLStmtIncoming_log_level = LOG + # multimaster.DDLProcessingTrace_log_level = LOG + + # multimaster.ProtoTraceFilter_log_level = LOG + # multimaster.ProtoTraceSender_log_level = LOG + # multimaster.ProtoTraceMessage_log_level = LOG + # multimaster.ProtoTraceState_log_level = LOG + + # multimaster.ReceiverState_log_level = LOG # multimaster.ReceiverStateDebug_log_level = LOG + # multimaster.ReceiverFilter_log_level = LOG # multimaster.ApplyMessage_log_level = LOG # multimaster.ApplyTrace_log_level = LOG + # multimaster.ApplyError_log_level = LOG + # multimaster.ApplyBgwFinish_log_level = LOG # multimaster.ReceiverFeedback_log_level = LOG + # multimaster.StateMessage_log_level = LOG + # multimaster.StateSwitch_log_level = LOG multimaster.StateDebug_log_level = LOG + + # multimaster.SyncpointCreated_log_level = LOG + # multimaster.SyncpointApply_log_level = LOG + + # multimaster.NodeMgmt_log_level = LOG }); $node->append_conf('pg_hba.conf', $hba); @@ -339,9 +469,21 @@ sub connstr sub add_node() { my ($self) = @_; + my $new_node; - my $new_node = get_new_node("node@{[$#{$self->{nodes}} + 2]}", - (port => mm_get_free_port())); + eval + { + if ($pg_15_modules) + { + $new_node = PostgreSQL::Test::Cluster->new("node@{[$#{$self->{nodes}} + 2]}", + (port => mm_get_free_port())); + } + else + { + $new_node = PostgresNode::get_new_node("node@{[$#{$self->{nodes}} + 2]}", + (port => mm_get_free_port())); + } + }; push(@{$self->{nodes}}, $new_node); return $#{$self->{nodes}}; diff --git a/Makefile b/Makefile index 994e04ff8a..19171ffacc 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,6 @@ all: multimaster.so submake-regress: $(MAKE) -C $(top_builddir)/src/test/regress all - $(MAKE) -C $(top_builddir)/src/test/regress tablespace-setup # all .pl tests should pass now, but let's see what the buildfarm says # ifndef MTM_ALL diff --git a/expected/regression_ee.diff b/expected/regression_ee.diff index ebc60ab969..4814bbea27 100644 --- a/expected/regression_ee.diff +++ b/expected/regression_ee.diff @@ -1,7 +1,7 @@ diff ../../../src/test/regress/expected/create_table.out ../tmp_check/regress_outdir/results/create_table.out --- ../../../src/test/regress/expected/create_table.out CENSORED +++ ../tmp_check/regress_outdir/results/create_table.out CENSORED -@@ -263,17 +263,17 @@ +@@ -58,17 +58,17 @@ DROP TABLE as_select1; PREPARE select1 AS SELECT 1 as a; CREATE TABLE as_select1 AS EXECUTE select1; @@ -29,7 +29,7 @@ diff ../../../src/test/regress/expected/create_table.out ../tmp_check/regress_ou diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_outdir/results/create_index.out --- ../../../src/test/regress/expected/create_index.out CENSORED +++ ../tmp_check/regress_outdir/results/create_index.out CENSORED -@@ -1394,31 +1394,33 @@ +@@ -1389,31 +1389,33 @@ CREATE TABLE concur_heap (f1 text, f2 text); -- empty table CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1); @@ -70,7 +70,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou COMMIT; -- test where predicate is able to do a transactional update during -- a concurrent build before switching pg_index state flags. -@@ -1430,7 +1432,9 @@ +@@ -1425,7 +1427,9 @@ END; $$; CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) WHERE predicate_stable(); @@ -80,7 +80,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DROP FUNCTION predicate_stable(); -- But you can do a regular index build in a transaction BEGIN; -@@ -1439,8 +1443,6 @@ +@@ -1434,8 +1438,6 @@ -- Failed builds are left invalid by VACUUM FULL, fixed by REINDEX VACUUM FULL concur_heap; REINDEX TABLE concur_heap; @@ -89,7 +89,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DELETE FROM concur_heap WHERE f1 = 'b'; VACUUM FULL concur_heap; \d concur_heap -@@ -1450,12 +1452,6 @@ +@@ -1445,12 +1447,6 @@ f1 | text | | | f2 | text | | | Indexes: @@ -102,7 +102,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou "std_index" btree (f2) REINDEX TABLE concur_heap; -@@ -1466,12 +1462,6 @@ +@@ -1461,12 +1457,6 @@ f1 | text | | | f2 | text | | | Indexes: @@ -115,7 +115,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou "std_index" btree (f2) -- Temporary tables with concurrent builds and on-commit actions -@@ -1481,7 +1471,9 @@ +@@ -1476,7 +1466,9 @@ ON COMMIT PRESERVE ROWS; INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); @@ -125,7 +125,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DROP TABLE concur_temp; -- ON COMMIT DROP BEGIN; -@@ -1490,34 +1482,42 @@ +@@ -1485,34 +1477,42 @@ INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); -- Fails when running in a transaction. CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); @@ -172,7 +172,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou \d concur_heap Table "public.concur_heap" Column | Type | Collation | Nullable | Default -@@ -2474,46 +2474,38 @@ +@@ -2600,46 +2600,38 @@ INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); -- This trick creates an invalid index. CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); @@ -260,71 +260,62 @@ diff ../../../src/test/regress/expected/index_including_gist.out ../tmp_check/re DROP TABLE tbl_gist; /* -diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_outdir/results/sanity_check.out ---- ../../../src/test/regress/expected/sanity_check.out CENSORED -+++ ../tmp_check/regress_outdir/results/sanity_check.out CENSORED -@@ -11,6 +11,8 @@ - FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace - WHERE relkind IN ('r', 'p') AND (nspname ~ '^pg_temp_') IS NOT TRUE - ORDER BY relname; -+_pg_publication|t -+_pg_subscription|t - a|f - a_star|f - aggtest|f -@@ -32,6 +34,8 @@ - check_tbl|f - circle_tbl|t - city|f -+cluster_nodes|t -+config|t - copy_tbl|f - d|f - d_star|f -@@ -67,6 +71,7 @@ - jtbl|t - kd_point_tbl|t - line_tbl|f -+local_tables|t - log_table|f - lseg_tbl|f - main_table|f -@@ -83,6 +88,7 @@ - mlparted_defd|f - money_data|f - mytable|t -+nodes_init_done|t - num_data|f - num_exp_add|t - num_exp_div|t -@@ -140,7 +146,6 @@ - pg_policy|t - pg_proc|t - pg_profile|t --pg_publication|t - pg_publication_rel|t - pg_range|t - pg_replication_origin|t -@@ -154,7 +159,6 @@ - pg_statistic|t - pg_statistic_ext|t - pg_statistic_ext_data|t --pg_subscription|t - pg_subscription_rel|t - pg_tablespace|t - pg_transform|t -@@ -185,6 +189,7 @@ - sql_sizing|f - stud_emp|f - student|f -+syncpoints|t - tab_core_types|f - tableam_parted_a_heap2|f - tableam_parted_b_heap2|f +diff ../../../src/test/regress/expected/select_into.out ../tmp_check/regress_outdir/results/select_into.out +--- ../../../src/test/regress/expected/select_into.out CENSORED ++++ ../tmp_check/regress_outdir/results/select_into.out CENSORED +@@ -50,27 +50,19 @@ + PREPARE data_sel AS SELECT generate_series(1,3); + CREATE TABLE selinto_schema.tbl_withdata3 (a) AS + EXECUTE data_sel WITH DATA; ++ERROR: [MTM] failed to prepare transaction at peer node + EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata4 (a) AS + EXECUTE data_sel WITH DATA; +- QUERY PLAN +--------------------------------------- +- ProjectSet (actual rows=3 loops=1) +- -> Result (actual rows=1 loops=1) +-(2 rows) +- ++ERROR: [MTM] failed to prepare transaction at peer node + -- EXECUTE and WITH NO DATA, passes. + CREATE TABLE selinto_schema.tbl_nodata3 (a) AS + EXECUTE data_sel WITH NO DATA; ++ERROR: [MTM] failed to prepare transaction at peer node + EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata4 (a) AS + EXECUTE data_sel WITH NO DATA; +- QUERY PLAN +-------------------------------- +- ProjectSet (never executed) +- -> Result (never executed) +-(2 rows) +- ++ERROR: [MTM] failed to prepare transaction at peer node + RESET SESSION AUTHORIZATION; + ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + GRANT INSERT ON TABLES TO regress_selinto_user; +@@ -78,15 +70,11 @@ + RESET SESSION AUTHORIZATION; + DEALLOCATE data_sel; + DROP SCHEMA selinto_schema CASCADE; +-NOTICE: drop cascades to 8 other objects ++NOTICE: drop cascades to 4 other objects + DETAIL: drop cascades to table selinto_schema.tbl_withdata1 + drop cascades to table selinto_schema.tbl_withdata2 + drop cascades to table selinto_schema.tbl_nodata1 + drop cascades to table selinto_schema.tbl_nodata2 +-drop cascades to table selinto_schema.tbl_withdata3 +-drop cascades to table selinto_schema.tbl_withdata4 +-drop cascades to table selinto_schema.tbl_nodata3 +-drop cascades to table selinto_schema.tbl_nodata4 + DROP USER regress_selinto_user; + -- Tests for WITH NO DATA and column name consistency + CREATE TABLE ctas_base (i int, j int); diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_outdir/results/transactions.out --- ../../../src/test/regress/expected/transactions.out CENSORED +++ ../tmp_check/regress_outdir/results/transactions.out CENSORED -@@ -685,50 +685,38 @@ +@@ -689,50 +689,38 @@ INSERT INTO abc VALUES (1); INSERT INTO abc VALUES (2); COMMIT AND CHAIN; -- TBLOCK_END @@ -384,7 +375,7 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou COMMIT; START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; SHOW transaction_isolation; -@@ -796,24 +784,13 @@ +@@ -800,24 +788,13 @@ SAVEPOINT x; COMMIT AND CHAIN; -- TBLOCK_SUBCOMMIT @@ -413,7 +404,7 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou COMMIT; -- different mix of options just for fun START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE; -@@ -881,17 +858,14 @@ +@@ -885,17 +862,14 @@ ROLLBACK; -- not allowed outside a transaction block COMMIT AND CHAIN; -- error @@ -433,8 +424,8 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou RESET default_transaction_read_only; DROP TABLE abc; -@@ -981,7 +955,7 @@ - SELECT 1\; BEGIN\; SAVEPOINT sp\; ROLLBACK TO SAVEPOINT sp\; COMMIT; +@@ -1041,7 +1015,7 @@ + -- Tests for AND CHAIN in implicit transaction blocks SET TRANSACTION READ ONLY\; COMMIT AND CHAIN; -- error -ERROR: COMMIT AND CHAIN can only be used in transaction blocks @@ -442,7 +433,7 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou SHOW transaction_read_only; transaction_read_only ----------------------- -@@ -1000,23 +974,20 @@ +@@ -1060,23 +1034,20 @@ -- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN INSERT INTO abc VALUES (7)\; COMMIT\; INSERT INTO abc VALUES (8)\; COMMIT AND CHAIN; -- 7 commit, 8 error WARNING: there is no transaction in progress @@ -470,8 +461,8 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou COMMIT; START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok SHOW transaction_isolation; -- transaction is active at this point -@@ -1028,7 +999,7 @@ - ROLLBACK; +@@ -1089,7 +1060,7 @@ + SET default_transaction_isolation = 'read committed'; -- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error -ERROR: COMMIT AND CHAIN can only be used in transaction blocks @@ -479,7 +470,7 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou SHOW transaction_isolation; -- out of transaction block transaction_isolation ----------------------- -@@ -1047,9 +1018,8 @@ +@@ -1109,9 +1080,8 @@ a ---- 7 @@ -490,6 +481,24 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou DROP TABLE abc; -- Test for successful cleanup of an aborted transaction at session exit. +diff ../../../src/test/regress/expected/portals.out ../tmp_check/regress_outdir/results/portals.out +--- ../../../src/test/regress/expected/portals.out CENSORED ++++ ../tmp_check/regress_outdir/results/portals.out CENSORED +@@ -1553,11 +1553,9 @@ + + declare held_portal cursor with hold for select * from toasted_data; + commit; ++ERROR: cannot PREPARE a transaction that has created a cursor WITH HOLD + drop table toasted_data; ++ERROR: table "toasted_data" does not exist + fetch all in held_portal; +- f1 +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +- {12345678,12345679,12345680,12345681,12345682,12345683,12345684,12345685,12345686,12345687,12345688,12345689,12345690,12345691,12345692,12345693,12345694,12345695,12345696,12345697,12345698,12345699,12345700,12345701,12345702,12345703,12345704,12345705,12345706,12345707,12345708,12345709,12345710,12345711,12345712,12345713,12345714,12345715,12345716,12345717,12345718,12345719,12345720,12345721,12345722,12345723,12345724,12345725,12345726,12345727,12345728,12345729,12345730,12345731,12345732,12345733,12345734,12345735,12345736,12345737,12345738,12345739,12345740,12345741,12345742,12345743,12345744,12345745,12345746,12345747,12345748,12345749,12345750,12345751,12345752,12345753,12345754,12345755,12345756,12345757,12345758,12345759,12345760,12345761,12345762,12345763,12345764,12345765,12345766,12345767,12345768,12345769,12345770,12345771,12345772,12345773,12345774,12345775,12345776,12345777,12345778,12345779,12345780,12345781,12345782,12345783,12345784,12345785,12345786,12345787,12345788,12345789,12345790,12345791,12345792,12345793,12345794,12345795,12345796,12345797,12345798,12345799,12345800,12345801,12345802,12345803,12345804,12345805,12345806,12345807,12345808,12345809,12345810,12345811,12345812,12345813,12345814,12345815,12345816,12345817,12345818,12345819,12345820,12345821,12345822,12345823,12345824,12345825,12345826,12345827,12345828,12345829,12345830,12345831,12345832,12345833,12345834,12345835,12345836,12345837,12345838,12345839,12345840,12345841,12345842,12345843,12345844,12345845,12345846,12345847,12345848,12345849,12345850,12345851,12345852,12345853,12345854,12345855,12345856,12345857,12345858,12345859,12345860,12345861,12345862,12345863,12345864,12345865,12345866,12345867,12345868,12345869,12345870,12345871,12345872,12345873,12345874,12345875,12345876,12345877,12345878,12345879,12345880,12345881,12345882,12345883,12345884,12345885,12345886,12345887,12345888,12345889,12345890,12345891,12345892,12345893,12345894,12345895,12345896,12345897,12345898,12345899,12345900,12345901,12345902,12345903,12345904,12345905,12345906,12345907,12345908,12345909,12345910,12345911,12345912,12345913,12345914,12345915,12345916,12345917,12345918,12345919,12345920,12345921,12345922,12345923,12345924,12345925,12345926,12345927,12345928,12345929,12345930,12345931,12345932,12345933,12345934,12345935,12345936,12345937,12345938,12345939,12345940,12345941,12345942,12345943,12345944,12345945,12345946,12345947,12345948,12345949,12345950,12345951,12345952,12345953,12345954,12345955,12345956,12345957,12345958,12345959,12345960,12345961,12345962,12345963,12345964,12345965,12345966,12345967,12345968,12345969,12345970,12345971,12345972,12345973,12345974,12345975,12345976,12345977,12345978,12345979,12345980,12345981,12345982,12345983,12345984,12345985,12345986,12345987,12345988,12345989,12345990,12345991,12345992,12345993,12345994,12345995,12345996,12345997,12345998,12345999,12346000,12346001,12346002,12346003,12346004,12346005,12346006,12346007,12346008,12346009,12346010,12346011,12346012,12346013,12346014,12346015,12346016,12346017,12346018,12346019,12346020,12346021,12346022,12346023,12346024,12346025,12346026,12346027,12346028,12346029,12346030,12346031,12346032,12346033,12346034,12346035,12346036,12346037,12346038,12346039,12346040,12346041,12346042,12346043,12346044,12346045,12346046,12346047,12346048,12346049,12346050,12346051,12346052,12346053,12346054,12346055,12346056,12346057,12346058,12346059,12346060,12346061,12346062,12346063,12346064,12346065,12346066,12346067,12346068,12346069,12346070,12346071,12346072,12346073,12346074,12346075,12346076,12346077,12346078,12346079,12346080,12346081,12346082,12346083,12346084,12346085,12346086,12346087,12346088,12346089,12346090,12346091,12346092,12346093,12346094,12346095,12346096,12346097,12346098,12346099,12346100,12346101,12346102,12346103,12346104,12346105,12346106,12346107,12346108,12346109,12346110,12346111,12346112,12346113,12346114,12346115,12346116,12346117,12346118,12346119,12346120,12346121,12346122,12346123,12346124,12346125,12346126,12346127,12346128,12346129,12346130,12346131,12346132,12346133,12346134,12346135,12346136,12346137,12346138,12346139,12346140,12346141,12346142,12346143,12346144,12346145,12346146,12346147,12346148,12346149,12346150,12346151,12346152,12346153,12346154,12346155,12346156,12346157,12346158,12346159,12346160,12346161,12346162,12346163,12346164,12346165,12346166,12346167,12346168,12346169,12346170,12346171,12346172,12346173,12346174,12346175,12346176,12346177,12346178,12346179,12346180,12346181,12346182,12346183,12346184,12346185,12346186,12346187,12346188,12346189,12346190,12346191,12346192,12346193,12346194,12346195,12346196,12346197,12346198,12346199,12346200,12346201,12346202,12346203,12346204,12346205,12346206,12346207,12346208,12346209,12346210,12346211,12346212,12346213,12346214,12346215,12346216,12346217,12346218,12346219,12346220,12346221,12346222,12346223,12346224,12346225,12346226,12346227,12346228,12346229,12346230,12346231,12346232,12346233,12346234,12346235,12346236,12346237,12346238,12346239,12346240,12346241,12346242,12346243,12346244,12346245,12346246,12346247,12346248,12346249,12346250,12346251,12346252,12346253,12346254,12346255,12346256,12346257,12346258,12346259,12346260,12346261,12346262,12346263,12346264,12346265,12346266,12346267,12346268,12346269,12346270,12346271,12346272,12346273,12346274,12346275,12346276,12346277,12346278,12346279,12346280,12346281,12346282,12346283,12346284,12346285,12346286,12346287,12346288,12346289,12346290,12346291,12346292,12346293,12346294,12346295,12346296,12346297,12346298,12346299,12346300,12346301,12346302,12346303,12346304,12346305,12346306,12346307,12346308,12346309,12346310,12346311,12346312,12346313,12346314,12346315,12346316,12346317,12346318,12346319,12346320,12346321,12346322,12346323,12346324,12346325,12346326,12346327,12346328,12346329,12346330,12346331,12346332,12346333,12346334,12346335,12346336,12346337,12346338,12346339,12346340,12346341,12346342,12346343,12346344,12346345,12346346,12346347,12346348,12346349,12346350,12346351,12346352,12346353,12346354,12346355,12346356,12346357,12346358,12346359,12346360,12346361,12346362,12346363,12346364,12346365,12346366,12346367,12346368,12346369,12346370,12346371,12346372,12346373,12346374,12346375,12346376,12346377,12346378,12346379,12346380,12346381,12346382,12346383,12346384,12346385,12346386,12346387,12346388,12346389,12346390,12346391,12346392,12346393,12346394,12346395,12346396,12346397,12346398,12346399,12346400,12346401,12346402,12346403,12346404,12346405,12346406,12346407,12346408,12346409,12346410,12346411,12346412,12346413,12346414,12346415,12346416,12346417,12346418,12346419,12346420,12346421,12346422,12346423,12346424,12346425,12346426,12346427,12346428,12346429,12346430,12346431,12346432,12346433,12346434,12346435,12346436,12346437,12346438,12346439,12346440,12346441,12346442,12346443,12346444,12346445,12346446,12346447,12346448,12346449,12346450,12346451,12346452,12346453,12346454,12346455,12346456,12346457,12346458,12346459,12346460,12346461,12346462,12346463,12346464,12346465,12346466,12346467,12346468,12346469,12346470,12346471,12346472,12346473,12346474,12346475,12346476,12346477,12346478,12346479,12346480,12346481,12346482,12346483,12346484,12346485,12346486,12346487,12346488,12346489,12346490,12346491,12346492,12346493,12346494,12346495,12346496,12346497,12346498,12346499,12346500,12346501,12346502,12346503,12346504,12346505,12346506,12346507,12346508,12346509,12346510,12346511,12346512,12346513,12346514,12346515,12346516,12346517,12346518,12346519,12346520,12346521,12346522,12346523,12346524,12346525,12346526,12346527,12346528,12346529,12346530,12346531,12346532,12346533,12346534,12346535,12346536,12346537,12346538,12346539,12346540,12346541,12346542,12346543,12346544,12346545,12346546,12346547,12346548,12346549,12346550,12346551,12346552,12346553,12346554,12346555,12346556,12346557,12346558,12346559,12346560,12346561,12346562,12346563,12346564,12346565,12346566,12346567,12346568,12346569,12346570,12346571,12346572,12346573,12346574,12346575,12346576,12346577,12346578,12346579,12346580,12346581,12346582,12346583,12346584,12346585,12346586,12346587,12346588,12346589,12346590,12346591,12346592,12346593,12346594,12346595,12346596,12346597,12346598,12346599,12346600,12346601,12346602,12346603,12346604,12346605,12346606,12346607,12346608,12346609,12346610,12346611,12346612,12346613,12346614,12346615,12346616,12346617,12346618,12346619,12346620,12346621,12346622,12346623,12346624,12346625,12346626,12346627,12346628,12346629,12346630,12346631,12346632,12346633,12346634,12346635,12346636,12346637,12346638,12346639,12346640,12346641,12346642,12346643,12346644,12346645,12346646,12346647,12346648,12346649,12346650,12346651,12346652,12346653,12346654,12346655,12346656,12346657,12346658,12346659,12346660,12346661,12346662,12346663,12346664,12346665,12346666,12346667,12346668,12346669,12346670,12346671,12346672,12346673,12346674,12346675,12346676,12346677,12346678} +-(1 row) +- ++ERROR: cursor "held_portal" does not exist + reset default_toast_compression; diff ../../../src/test/regress/expected/brin.out ../tmp_check/regress_outdir/results/brin.out --- ../../../src/test/regress/expected/brin.out CENSORED +++ ../tmp_check/regress_outdir/results/brin.out CENSORED @@ -503,112 +512,30 @@ diff ../../../src/test/regress/expected/brin.out ../tmp_check/regress_outdir/res -- vacuum the table, to discard TOAST data VACUUM brintest_3; -- retry insert with a different random-looking (but deterministic) value -diff ../../../src/test/regress/expected/rowsecurity.out ../tmp_check/regress_outdir/results/rowsecurity.out ---- ../../../src/test/regress/expected/rowsecurity.out CENSORED -+++ ../tmp_check/regress_outdir/results/rowsecurity.out CENSORED -@@ -113,30 +113,7 @@ - (3 rows) - - \d document -- Table "regress_rls_schema.document" -- Column | Type | Collation | Nullable | Default -----------+---------+-----------+----------+--------- -- did | integer | | not null | -- cid | integer | | | -- dlevel | integer | | not null | -- dauthor | name | | | -- dtitle | text | | | --Indexes: -- "document_pkey" PRIMARY KEY, btree (did) --Foreign-key constraints: -- "document_cid_fkey" FOREIGN KEY (cid) REFERENCES category(cid) --Policies: -- POLICY "p1" -- USING ((dlevel <= ( SELECT uaccount.seclv -- FROM uaccount -- WHERE (uaccount.pguser = CURRENT_USER)))) -- POLICY "p1r" AS RESTRICTIVE -- TO regress_rls_dave -- USING ((cid <> 44)) -- POLICY "p2r" AS RESTRICTIVE -- TO regress_rls_dave -- USING (((cid <> 44) AND (cid < 50))) -- -+ERROR: permission denied for view pg_publication - SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename = 'document' ORDER BY policyname; - schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check - --------------------+-----------+------------+-------------+--------------------+-----+--------------------------------------------+------------ -@@ -938,27 +915,7 @@ - CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave - USING (cid < 55); - \d+ part_document -- Partitioned table "regress_rls_schema.part_document" -- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description -----------+---------+-----------+----------+---------+----------+--------------+------------- -- did | integer | | | | plain | | -- cid | integer | | | | plain | | -- dlevel | integer | | not null | | plain | | -- dauthor | name | | | | plain | | -- dtitle | text | | | | extended | | --Partition key: RANGE (cid) --Policies: -- POLICY "pp1" -- USING ((dlevel <= ( SELECT uaccount.seclv -- FROM uaccount -- WHERE (uaccount.pguser = CURRENT_USER)))) -- POLICY "pp1r" AS RESTRICTIVE -- TO regress_rls_dave -- USING ((cid < 55)) --Partitions: part_document_fiction FOR VALUES FROM (11) TO (12), -- part_document_nonfiction FOR VALUES FROM (99) TO (100), -- part_document_satire FOR VALUES FROM (55) TO (56) -- -+ERROR: permission denied for view pg_publication - SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename like '%part_document%' ORDER BY policyname; - schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check - --------------------+---------------+------------+-------------+--------------------+-----+--------------------------------------------+------------ -diff ../../../src/test/regress/expected/atx.out ../tmp_check/regress_outdir/results/atx.out ---- ../../../src/test/regress/expected/atx.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx.out CENSORED -@@ -851,6 +851,7 @@ - declare c2 cursor with hold for select count_tt1_v(), count_tt1_s(); - insert into atx_tt1 values(2); - commit; -+ERROR: cannot PREPARE a transaction that has created a cursor WITH HOLD - commit; - begin; - begin autonomous; -@@ -866,6 +867,7 @@ - drop function count_tt1_s(); - drop table if exists atx_tt1; - close c2; -+ERROR: cursor "c2" does not exist - -- 13 - create table atx_13_t(i int); - begin; -@@ -985,9 +987,7 @@ - insert into atx_tt2 values(1); - declare c2 cursor with hold for select error_function(); - commit; --NOTICE: other exception 22012, division by zero --ERROR: control reached end of function without RETURN --CONTEXT: PL/pgSQL function error_function() -+ERROR: cannot PREPARE a transaction that has created a cursor WITH HOLD - commit; - drop function if exists error_function(); - drop table if exists atx_tt2; -@@ -1074,6 +1074,7 @@ - RESET client_min_messages; - create database regression_atx_test_database; - ALTER DATABASE "regression_atx_test_database" SET lc_messages TO 'C'; -+ERROR: [MTM] failed to prepare transaction at peer node - \c regression_atx_test_database - create table atx_test as select 1 as id; - begin; -diff ../../../src/test/regress/expected/atx5.out ../tmp_check/regress_outdir/results/atx5.out ---- ../../../src/test/regress/expected/atx5.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx5.out CENSORED -@@ -24,10 +24,7 @@ +diff ../../../src/test/regress/expected/privileges.out ../tmp_check/regress_outdir/results/privileges.out +--- ../../../src/test/regress/expected/privileges.out CENSORED ++++ ../tmp_check/regress_outdir/results/privileges.out CENSORED +@@ -1613,11 +1613,16 @@ + -- Do the same concurrently + CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); ++ERROR: multimaster doesn't support CREATE INDEX CONCURRENTLY + -- REINDEX + REINDEX TABLE sro_tab; ++NOTICE: table "sro_tab" has no indexes to reindex + REINDEX INDEX sro_idx; ++ERROR: relation "sro_idx" does not exist + REINDEX TABLE CONCURRENTLY sro_tab; ++NOTICE: table "sro_tab" has no indexes that can be reindexed concurrently + DROP INDEX sro_idx; ++ERROR: index "sro_idx" does not exist + -- CLUSTER + CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))); + CLUSTER sro_tab USING sro_cluster_idx; +diff ../../../src/test/regress/expected/atx3.out ../tmp_check/regress_outdir/results/atx3.out +--- ../../../src/test/regress/expected/atx3.out CENSORED ++++ ../tmp_check/regress_outdir/results/atx3.out CENSORED +@@ -115,10 +115,7 @@ NOTICE: function atx_test_30_one() does not exist, skipping NOTICE: function atx_test_30_one() does not exist, skipping NOTICE: function atx_test_30_one() does not exist, skipping @@ -620,10 +547,7 @@ diff ../../../src/test/regress/expected/atx5.out ../tmp_check/regress_outdir/res SET client_min_messages = 'warning'; DROP FUNCTION IF EXISTS atx_test_30_one(); DROP FUNCTION IF EXISTS atx_test_30_two(); -diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/results/atx9.out ---- ../../../src/test/regress/expected/atx9.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx9.out CENSORED -@@ -29,50 +29,38 @@ +@@ -547,50 +544,38 @@ INSERT INTO abc VALUES (1); INSERT INTO abc VALUES (2); COMMIT AND CHAIN; -- TBLOCK_END @@ -683,7 +607,7 @@ diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/res COMMIT; ROLLBACK; BEGIN; -@@ -144,24 +132,13 @@ +@@ -662,24 +647,13 @@ SAVEPOINT x; COMMIT AND CHAIN; -- TBLOCK_SUBCOMMIT @@ -712,7 +636,7 @@ diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/res COMMIT; ROLLBACK; -- different mix of options just for fun -@@ -232,17 +209,14 @@ +@@ -750,17 +724,14 @@ COMMIT; -- not allowed outside a transaction block COMMIT AUTONOMOUS AND CHAIN; -- error @@ -737,7 +661,7 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re +++ ../tmp_check/regress_outdir/results/rules.out CENSORED @@ -1285,6 +1285,15 @@ SELECT viewname, definition FROM pg_views - WHERE schemaname IN ('pg_catalog', 'public') + WHERE schemaname = 'pg_catalog' ORDER BY viewname; +_pg_prepared_xacts| SELECT p.transaction, + p.gid, @@ -748,13 +672,13 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re + FROM ((pg_prepared_xact() p(transaction, gid, prepared, ownerid, dbid, state3pc) + LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) + LEFT JOIN pg_database d ON ((p.dbid = d.oid))); - iexit| SELECT ih.name, - ih.thepath, - interpt_pp(ih.thepath, r.thepath) AS exit -@@ -1452,19 +1461,30 @@ - p.parameter_types, - p.from_sql - FROM pg_prepared_statement() p(name, statement, prepare_time, parameter_types, from_sql); + pg_available_extension_versions| SELECT e.name, + e.version, + (x.extname IS NOT NULL) AS installed, +@@ -1427,15 +1436,6 @@ + p.generic_plans, + p.custom_plans + FROM pg_prepared_statement() p(name, statement, prepare_time, parameter_types, from_sql, generic_plans, custom_plans); -pg_prepared_xacts| SELECT p.transaction, - p.gid, - p.prepared, @@ -764,111 +688,334 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re - FROM ((pg_prepared_xact() p(transaction, gid, prepared, ownerid, dbid, state3pc) - LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) - LEFT JOIN pg_database d ON ((p.dbid = d.oid))); -+pg_prepared_xacts| SELECT _pg_prepared_xacts.transaction, -+ _pg_prepared_xacts.gid, -+ _pg_prepared_xacts.prepared, -+ _pg_prepared_xacts.owner, -+ _pg_prepared_xacts.database, -+ _pg_prepared_xacts.state3pc -+ FROM _pg_prepared_xacts -+ WHERE (_pg_prepared_xacts.gid !~~ 'MTM-%'::text) -+ ORDER BY ((_pg_prepared_xacts.transaction)::text)::bigint; -+pg_publication| SELECT _pg_publication.oid, -+ _pg_publication.pubname, -+ _pg_publication.pubowner, -+ _pg_publication.puballtables, -+ _pg_publication.pubinsert, -+ _pg_publication.pubupdate, -+ _pg_publication.pubdelete, -+ _pg_publication.pubtruncate, -+ _pg_publication.pubviaroot -+ FROM _pg_publication -+ WHERE (_pg_publication.pubname <> 'multimaster'::name); pg_publication_tables| SELECT p.pubname, n.nspname AS schemaname, - c.relname AS tablename -- FROM pg_publication p, -+ FROM _pg_publication p, - LATERAL pg_get_publication_tables((p.pubname)::text) gpt(relid), - (pg_class c - JOIN pg_namespace n ON ((n.oid = c.relnamespace))) -@@ -1659,7 +1679,7 @@ - l.provider, - l.label - FROM (pg_seclabel l -- JOIN pg_publication p ON (((l.classoid = p.tableoid) AND (l.objoid = p.oid)))) -+ JOIN _pg_publication p ON (((l.classoid = p.tableoid) AND (l.objoid = p.oid)))) - WHERE (l.objsubid = 0) - UNION ALL - SELECT l.objoid, -@@ -1671,7 +1691,7 @@ - l.provider, - l.label - FROM (pg_shseclabel l -- JOIN pg_subscription s ON (((l.classoid = s.tableoid) AND (l.objoid = s.oid)))) -+ JOIN _pg_subscription s ON (((l.classoid = s.tableoid) AND (l.objoid = s.oid)))) - UNION ALL - SELECT l.objoid, - l.classoid, -@@ -2066,7 +2086,7 @@ - st.last_msg_receipt_time, - st.latest_end_lsn, - st.latest_end_time -- FROM (pg_subscription su -+ FROM (_pg_subscription su - LEFT JOIN pg_stat_get_subscription(NULL::oid) st(subid, relid, pid, received_lsn, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time) ON ((st.subid = su.oid))); - pg_stat_sys_indexes| SELECT pg_stat_all_indexes.relid, - pg_stat_all_indexes.indexrelid, -@@ -2408,6 +2428,17 @@ - FROM (unnest(s.stxkeys) k(k) - JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k)))) - WHERE (NOT has_column_privilege(c.oid, a.attnum, 'select'::text))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid)))); -+pg_subscription| SELECT _pg_subscription.oid, -+ _pg_subscription.subdbid, -+ _pg_subscription.subname, -+ _pg_subscription.subowner, -+ _pg_subscription.subenabled, -+ _pg_subscription.subconninfo, -+ _pg_subscription.subslotname, -+ _pg_subscription.subsynccommit, -+ _pg_subscription.subpublications -+ FROM _pg_subscription -+ WHERE (_pg_subscription.subname !~~ 'mtm_sub_%'::text); - pg_tables| SELECT n.nspname AS schemaname, c.relname AS tablename, - pg_get_userbyid(c.relowner) AS tableowner, +diff ../../../src/test/regress/expected/psql.out ../tmp_check/regress_outdir/results/psql.out +--- ../../../src/test/regress/expected/psql.out CENSORED ++++ ../tmp_check/regress_outdir/results/psql.out CENSORED +@@ -5292,6 +5292,7 @@ + BEGIN; + INSERT INTO oer_test VALUES (5); + COMMIT AND CHAIN; ++ERROR: [MTM] COMMIT AND CHAIN is not supported + INSERT INTO oer_test VALUES (6); + COMMIT; + SELECT * FROM oer_test; diff ../../../src/test/regress/expected/publication.out ../tmp_check/regress_outdir/results/publication.out --- ../../../src/test/regress/expected/publication.out CENSORED +++ ../tmp_check/regress_outdir/results/publication.out CENSORED -@@ -11,9 +11,9 @@ - RESET client_min_messages; - COMMENT ON PUBLICATION testpub_default IS 'test publication'; +@@ -13,8 +13,9 @@ SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p; -- obj_description -------------------- -- test publication -+ obj_description -+----------------- + obj_description + ------------------ + - (1 row) + test publication +-(1 row) ++(2 rows) SET client_min_messages = 'ERROR'; + CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert); +@@ -33,18 +34,20 @@ + List of publications + Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root + --------------------+--------------------------+------------+---------+---------+---------+-----------+---------- + testpib_ins_trunct | regress_publication_user | f | t | f | f | f | f + testpub_default | regress_publication_user | f | f | t | f | f | f +-(2 rows) ++(3 rows) + + ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete'); + \dRp + List of publications + Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root + --------------------+--------------------------+------------+---------+---------+---------+-----------+---------- + testpib_ins_trunct | regress_publication_user | f | t | f | f | f | f + testpub_default | regress_publication_user | f | t | t | t | f | f +-(2 rows) ++(3 rows) + + --- adding tables + CREATE SCHEMA pub_test; diff ../../../src/test/regress/expected/subscription.out ../tmp_check/regress_outdir/results/subscription.out --- ../../../src/test/regress/expected/subscription.out CENSORED +++ ../tmp_check/regress_outdir/results/subscription.out CENSORED -@@ -32,9 +32,9 @@ - WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables - COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; +@@ -34,8 +34,10 @@ SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; -- obj_description --------------------- -- test subscription -+ obj_description -+----------------- + obj_description + ------------------- + - (1 row) ++ + test subscription +-(1 row) ++(3 rows) -- fail - name already exists + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); +@@ -76,11 +78,13 @@ + ERROR: invalid connection string syntax: missing "=" after "foobar" in connection info string + + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); + ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; +@@ -96,11 +100,13 @@ + -- ok + ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/12345'); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+------------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | off | dbname=regress_doesnotexist2 | 0/12345 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | off | dbname=regress_doesnotexist2 | 0/12345 ++(3 rows) + + -- ok - with lsn = NONE + ALTER SUBSCRIPTION regress_testsub SKIP (lsn = NONE); +@@ -108,11 +114,13 @@ + ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/0'); + ERROR: invalid WAL location (LSN): 0/0 + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+------------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | off | dbname=regress_doesnotexist2 | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | off | dbname=regress_doesnotexist2 | 0/0 ++(3 rows) + + BEGIN; + ALTER SUBSCRIPTION regress_testsub ENABLE; +@@ -120,16 +128,20 @@ + List of subscriptions + Name | Owner | Enabled | Publication + -----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | t | {testpub2,testpub3} +-(1 row) ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub DISABLE; + \dRs + List of subscriptions + Name | Owner | Enabled | Publication + -----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | f | {testpub2,testpub3} +-(1 row) ++(3 rows) + + COMMIT; + -- fail - must be owner of subscription +@@ -143,11 +155,13 @@ + ERROR: invalid value for parameter "synchronous_commit": "foobar" + HINT: Available values: local, remote_write, remote_apply, on, off. + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +----------------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+------------------------------+---------- +- regress_testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | local | dbname=regress_doesnotexist2 | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++---------------------+---------------------------+---------+---------------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | f | f | d | f | local | dbname=regress_doesnotexist2 | 0/0 ++(3 rows) + + -- rename back to keep the rest simple + ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; +@@ -179,20 +193,24 @@ + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = true); + WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | t | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | t | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (binary = false); + ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + DROP SUBSCRIPTION regress_testsub; + -- fail - streaming must be boolean +@@ -202,20 +220,24 @@ + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true); + WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | t | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | t | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (streaming = false); + ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + -- fail - publication already exists + ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub WITH (refresh = false); +@@ -229,11 +251,13 @@ + ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false); + ERROR: publication "testpub1" is already in subscription "regress_testsub" + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-----------------------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub,testpub1,testpub2} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+-----------------------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub,testpub1,testpub2} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + -- fail - publication used more then once + ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub1 WITH (refresh = false); +@@ -247,11 +271,13 @@ + -- ok - delete publications + ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub2 WITH (refresh = false); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + DROP SUBSCRIPTION regress_testsub; + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub +@@ -284,11 +310,13 @@ + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = true); + WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | p | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | p | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + --fail - alter of two_phase option not supported. + ALTER SUBSCRIPTION regress_testsub SET (two_phase = false); +@@ -296,11 +324,13 @@ + -- but can alter streaming when two_phase enabled + ALTER SUBSCRIPTION regress_testsub SET (streaming = true); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | t | p | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | t | p | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + DROP SUBSCRIPTION regress_testsub; +@@ -308,11 +338,13 @@ + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true, two_phase = true); + WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | t | p | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | t | p | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + DROP SUBSCRIPTION regress_testsub; +@@ -323,19 +355,23 @@ + CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = false); + WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | f | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (disable_on_error = true); + \dRs+ +- List of subscriptions +- Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN +------------------+---------------------------+---------+-------------+--------+-----------+------------------+------------------+--------------------+-----------------------------+---------- +- regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | t | off | dbname=regress_doesnotexist | 0/0 +-(1 row) ++ List of subscriptions ++ Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Synchronous commit | Conninfo | Skip LSN ++-----------------+---------------------------+---------+---------------+--------+-----------+------------------+------------------+--------------------+-----------------------------------------------+---------- ++ regress_testsub | regress_subscription_user | f | {testpub} | f | f | d | t | off | dbname=regress_doesnotexist | 0/0 ++(3 rows) + + ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + DROP SUBSCRIPTION regress_testsub; diff ../../../src/test/regress/expected/prepare.out ../tmp_check/regress_outdir/results/prepare.out --- ../../../src/test/regress/expected/prepare.out CENSORED +++ ../tmp_check/regress_outdir/results/prepare.out CENSORED @@ -927,7 +1074,7 @@ diff ../../../src/test/regress/expected/indexing.out ../tmp_check/regress_outdir drop table idxpart; -- Verify bugfix with query on indexed partitioned table with no partitions -- https://postgr.es/m/20180124162006.pmapfiznhgngwtjf@alvherre.pgsql -@@ -175,7 +175,7 @@ +@@ -176,7 +176,7 @@ ERROR: cannot drop index idxpart1_a_idx because index idxpart_a_idx requires it HINT: You can drop index idxpart_a_idx instead. drop index concurrently idxpart_a_idx; -- unsupported @@ -936,7 +1083,7 @@ diff ../../../src/test/regress/expected/indexing.out ../tmp_check/regress_outdir drop index idxpart_a_idx; -- both indexes go away select relname, relkind from pg_class where relname like 'idxpart%' order by relname; -@@ -206,12 +206,14 @@ +@@ -207,12 +207,14 @@ HINT: You can drop index idxpart_temp_a_idx instead. -- non-concurrent drop is enforced here, so it is a valid case. drop index concurrently idxpart_temp_a_idx; diff --git a/run.pl b/run.pl index de4b018891..f3a13d945e 100755 --- a/run.pl +++ b/run.pl @@ -27,17 +27,44 @@ $cluster->create_mm('regression'); # prevent PostgresNode.pm from shutting down nodes on exit in END {} - @PostgresNode::all_nodes = (); + eval + { + if ($Cluster::pg_15_modules) + { + @PostgreSQL::Test::Cluster::all_nodes = (); + } + else + { + @PostgresNode::all_nodes = (); + } + }; } elsif ($action eq "stop") { - my @datas = <$TestLib::tmp_check/*data>; - foreach my $data (@datas) { - TestLib::system_log('pg_ctl', - '-D', "$data/pgdata", - '-m', 'fast', - 'stop'); - } + eval + { + if ($Cluster::pg_15_modules) + { + my @datas = <$PostgreSQL::Test::Utils::tmp_check/*data>; + foreach my $data (@datas) { + PostgreSQL::Test::Utils::system_log('pg_ctl', + '-D', "$data/pgdata", + '-m', 'fast', + 'stop'); + } + @PostgreSQL::Test::Cluster::all_nodes = (); + } + else + { + my @datas = <$TestLib::tmp_check/*data>; + foreach my $data (@datas) { + TestLib::system_log('pg_ctl', + '-D', "$data/pgdata", + '-m', 'fast', + 'stop'); + } + } + }; } else { diff --git a/src/commit.c b/src/commit.c index 0018c0b467..4e9d3c5505 100644 --- a/src/commit.c +++ b/src/commit.c @@ -135,14 +135,39 @@ mtm_commit_cleanup(int status, Datum arg) /* there was no precommit, we can abort */ PG_TRY(); { - AbortOutOfAnyTransaction(); - StartTransactionCommand(); +#ifdef PGPRO_EE + int atxLevel = DatumGetInt32(arg); + + /* + * If we are inside ATX transaction, we can not call + * AbortOutOfAnyTransaction() because this call will abort + * ALL transactions and we will have problems if the + * calling code is not designed for this case. + */ + if (atxLevel) + { + /* Abort (current ATX transaction only): */ + AbortCurrentTransaction(); + /* Restart ATX transaction if it was resumed: */ + if (atxLevel > getNestLevelATX()) + SuspendTransaction(); + } + else +#endif + { + AbortOutOfAnyTransaction(); + StartTransactionCommand(); + } FinishPreparedTransaction(mtm_commit_state.gid, false, false); mtm_commit_state.gtx->state.status = GTXAborted; mtm_log(MtmTxFinish, "%s aborted as own orphaned not precomitted", mtm_commit_state.gid); CommitTransactionCommand(); - +#ifdef PGPRO_EE + /* Restart ATX transaction if it was resumed: */ + if (atxLevel > getNestLevelATX()) + SuspendTransaction(); +#endif } /* * this should be extremely unlikely, but if we fail, don't @@ -218,7 +243,7 @@ MtmBeginTransaction() * register gtx hook first (it will be called last) */ GlobalTxEnsureBeforeShmemExitHook(); - before_shmem_exit(mtm_commit_cleanup, Int32GetDatum(1)); + before_shmem_exit(mtm_commit_cleanup, Int32GetDatum(0)); mtm_commit_state.mctx = AllocSetContextCreate(TopMemoryContext, "MtmCommitContext", ALLOCSET_DEFAULT_SIZES); @@ -373,6 +398,9 @@ MtmTwoPhaseCommit(void) MtmGeneration xact_gen; char dmq_stream_name[DMQ_STREAM_NAME_MAXLEN]; GTxState gtx_state; +#ifdef PGPRO_EE + int atxLevel = getNestLevelATX(); +#endif if (MtmNo3PC) { @@ -714,7 +742,11 @@ MtmTwoPhaseCommit(void) } PG_CATCH(); { +#ifdef PGPRO_EE + mtm_commit_cleanup(0, Int32GetDatum(atxLevel)); +#else mtm_commit_cleanup(0, Int32GetDatum(0)); +#endif PG_RE_THROW(); } diff --git a/src/ddl.c b/src/ddl.c index 49ccc2d0c4..39955dae6c 100644 --- a/src/ddl.c +++ b/src/ddl.c @@ -119,19 +119,21 @@ static void MtmSeqNextvalHook(Oid seqid, int64 next); static void MtmExecutorStart(QueryDesc *queryDesc, int eflags); static void MtmExecutorFinish(QueryDesc *queryDesc); -static void MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, +static void MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); static void MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); static void MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); @@ -139,6 +141,7 @@ static void MtmProcessUtilitySender(PlannedStmt *pstmt, static void MtmGucUpdate(const char *key); static void MtmInitializeRemoteFunctionsMap(void); static char *MtmGucSerialize(void); +static void MtmGucSync(const char *prefix); static void MtmMakeRelationLocal(Oid relid, bool locked); static List *AdjustCreateSequence(List *options); @@ -148,6 +151,11 @@ static void MtmFinishDDLCommand(void); PG_FUNCTION_INFO_V1(mtm_make_table_local); +#if PG_VERSION_NUM >= 150000 +static shmem_request_hook_type prev_shmem_request_hook = NULL; +static void mtm_ddl_shmem_request(void); +#endif + /***************************************************************************** * * Init @@ -157,6 +165,10 @@ PG_FUNCTION_INFO_V1(mtm_make_table_local); void MtmDDLReplicationInit() { +#if PG_VERSION_NUM >= 150000 + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = mtm_ddl_shmem_request; +#else Size size = 0; size = add_size(size, sizeof(struct DDLSharedState)); @@ -167,6 +179,7 @@ MtmDDLReplicationInit() RequestAddinShmemSpace(size); RequestNamedLWLockTranche("mtm-ddl", 1); +#endif PreviousExecutorStartHook = ExecutorStart_hook; ExecutorStart_hook = MtmExecutorStart; @@ -181,6 +194,25 @@ MtmDDLReplicationInit() SeqNextvalHook = MtmSeqNextvalHook; } +#if PG_VERSION_NUM >= 150000 +static void +mtm_ddl_shmem_request(void) +{ + Size size = 0; + + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + + size = add_size(size, sizeof(struct DDLSharedState)); + size = add_size(size, hash_estimate_size(MULTIMASTER_MAX_LOCAL_TABLES, + sizeof(Oid))); + size = MAXALIGN(size); + + RequestAddinShmemSpace(size); + RequestNamedLWLockTranche("mtm-ddl", 1); +} +#endif + void MtmDDLReplicationShmemStartup(void) { @@ -359,7 +391,7 @@ MtmGucInit(void) MtmGucHash = hash_create("MtmGucHash", MTM_GUC_HASHSIZE, &hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); /* * If current role is not equal to MtmDatabaseUser, than set it before any @@ -614,6 +646,71 @@ MtmGucSerialize(void) return serialized_gucs->data; } +/* + * Any loaded extension can set ist own parameters + * replacing existing placeholders if needed + * and reserve its own parameter pefix. + * Then all remaining placeholders with this prefix are deleted. + * Multimaster guc list MtmGucEntry should be updated also. + * This version just removes parameters which: + * - have reserved prefixes, + * - are not in guc variables list now. + * + * XXX: Can module name be used as a reserved prefix? + * + * XXX: Is it better to store placeholder flag in MtmGucEntry? + * + */ +void +MtmGucSync(const char *prefix) +{ + dlist_mutable_iter iter; + + if (!MtmGucHash) + MtmGucInit(); + + dlist_foreach_modify(iter, &MtmGucList) + { + MtmGucEntry *cur_entry = dlist_container(MtmGucEntry, list_node, iter.cur); + struct config_generic *gconf; + bool is_reserved_class = false; + const char *sep = strchr(cur_entry->key, GUC_QUALIFIER_SEPARATOR); + size_t classLen; + ListCell *lc; + + if (sep == NULL) + /* leave if is not prefixed */ + continue; + + classLen = sep - cur_entry->key; + foreach(lc, reserved_class_prefix) + { + const char *rcprefix = lfirst(lc); + + if (strlen(rcprefix) == classLen && + strncmp(cur_entry->key, rcprefix, classLen) == 0) + { + elog(LOG, "----> MtmGucSerialize: invalid configuration parameter name \"%s\": " + "\"%s\" is a reserved prefix.", + cur_entry->key, rcprefix); + is_reserved_class = true; + break; + } + } + + if (!is_reserved_class) + /* leave if prefix is not rerserved */ + continue; + + gconf = fing_guc_conf(cur_entry->key); + if (gconf) + /* leave if is in guc variable list */ + continue; + + dlist_delete(iter.cur); + hash_search(MtmGucHash, cur_entry->key, HASH_REMOVE, NULL); + } +} /***************************************************************************** @@ -656,12 +753,13 @@ MtmProcessDDLCommand(char const *queryString, bool transactional, static void MtmFinishDDLCommand() { - LogLogicalMessage("E", "", 1, true); + const char *msg = "MTM Finish DDL Command"; + LogLogicalMessage("E", msg, strlen(msg) + 1, true); } static void -MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -676,13 +774,13 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, { if (PreviousProcessUtilityHook != NULL) { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } else { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -691,12 +789,12 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, if (MtmIsLogicalReceiver) { - MtmProcessUtilityReceiver(pstmt, queryString, context, params, + MtmProcessUtilityReceiver(pstmt, queryString, context, readOnlyTree, params, queryEnv, dest, qc); } else { - MtmProcessUtilitySender(pstmt, queryString, context, params, + MtmProcessUtilitySender(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -718,7 +816,7 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, * receiver (e.g calling DDL from trigger) this hook does nothing. */ static void -MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -839,22 +937,18 @@ MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, } if (PreviousProcessUtilityHook != NULL) - { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } else - { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } } static void -MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -938,6 +1032,10 @@ MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, MtmExplicitFinishPrepared(isTopLevel, stmt->gid, false); return; + case TRANS_STMT_ROLLBACK_TO: + MtmDDLResetStatement(); + break; + default: break; } @@ -1186,17 +1284,13 @@ MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, stmt_string, skipCommand, MtmDDLStatement != NULL); if (PreviousProcessUtilityHook != NULL) - { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } else - { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } /* Catch GUC assignment */ if (nodeTag(parsetree) == T_VariableSetStmt) @@ -1209,6 +1303,14 @@ MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, } } + /* Catch GUC changes after LOAD */ + if (nodeTag(parsetree) == T_LoadStmt) + { + LoadStmt *stmt = (LoadStmt *) parsetree; + + MtmGucSync(stmt->filename); + } + if (executed) { MtmFinishDDLCommand(); @@ -1311,11 +1413,12 @@ MtmExecutorFinish(QueryDesc *queryDesc) if (operation == CMD_INSERT || operation == CMD_UPDATE || operation == CMD_DELETE || pstmt->hasModifyingCTE) { - int i; + ListCell *l; - for (i = 0; i < estate->es_num_result_relations; i++) + foreach(l, estate->es_opened_result_relations) { - Relation rel = estate->es_result_relations[i].ri_RelationDesc; + ResultRelInfo *resultRelInfo = lfirst(l); + Relation rel = resultRelInfo->ri_RelationDesc; /* * Don't run 3pc unless we modified at least one non-local table. @@ -1526,7 +1629,7 @@ MtmDDLResetApplyState() DDLApplyInProgress = false; /* the memory it points to is about to go away */ debug_query_string = NULL; - pgstat_report_activity(STATE_RUNNING, NULL); + pgstat_report_activity(STATE_IDLE, ""); } @@ -1709,7 +1812,7 @@ MtmInitializeRemoteFunctionsMap() if (q != NULL) *q++ = '\0'; - clist = FuncnameGetCandidates(stringToQualifiedNameList(p), -1, NIL, false, false, true); + clist = FuncnameGetCandidates(stringToQualifiedNameList(p), -1, NIL, false, false, true, true); if (clist == NULL) mtm_log(DEBUG1, "Can't resolve function '%s', postponing that", p); else @@ -1724,7 +1827,7 @@ MtmInitializeRemoteFunctionsMap() p = q; } while (p != NULL); - clist = FuncnameGetCandidates(stringToQualifiedNameList("mtm.alter_sequences"), -1, NIL, false, false, true); + clist = FuncnameGetCandidates(stringToQualifiedNameList("mtm.alter_sequences"), -1, NIL, false, false, true, true); if (clist != NULL) hash_search(MtmRemoteFunctions, &clist->oid, HASH_ENTER, NULL); diff --git a/src/dmq.c b/src/dmq.c index c2d14fae28..48fe1430a5 100644 --- a/src/dmq.c +++ b/src/dmq.c @@ -44,7 +44,9 @@ #include "utils/builtins.h" #include "utils/timestamp.h" #include "storage/shm_toc.h" +#include "postmaster/autovacuum.h" #include "postmaster/interrupt.h" +#include "replication/walsender.h" #include "storage/shm_mq.h" #include "storage/ipc.h" #include "tcop/tcopprot.h" @@ -238,6 +240,11 @@ static volatile sig_atomic_t got_SIGHUP = false; static shmem_startup_hook_type PreviousShmemStartupHook; +#if PG_VERSION_NUM >= 150000 +static shmem_request_hook_type prev_shmem_request_hook = NULL; +static void mtm_dmq_shmem_request(void); +#endif + void *(*dmq_receiver_start_hook)(char *sender_name); dmq_hook_type dmq_receiver_stop_hook; dmq_hook_type dmq_sender_connect_hook; @@ -353,7 +360,7 @@ dmq_shmem_startup_hook(void) DMQ_MAX_SUBS_PER_BACKEND * MaxBackends, DMQ_MAX_SUBS_PER_BACKEND * MaxBackends, &hash_info, - HASH_ELEM); + HASH_ELEM | HASH_STRINGS); LWLockRelease(AddinShmemInitLock); } @@ -362,10 +369,19 @@ static Size dmq_shmem_size(void) { Size size = 0; +#if PG_VERSION_NUM < 150000 + int maxbackends = MaxConnections + autovacuum_max_workers + + max_worker_processes + max_wal_senders + 1; +#endif size = add_size(size, sizeof(struct DmqSharedState)); +#if PG_VERSION_NUM >= 150000 size = add_size(size, hash_estimate_size(DMQ_MAX_SUBS_PER_BACKEND * MaxBackends, sizeof(DmqStreamSubscription))); +#else + size = add_size(size, hash_estimate_size(DMQ_MAX_SUBS_PER_BACKEND * maxbackends, + sizeof(DmqStreamSubscription))); +#endif return MAXALIGN(size); } @@ -378,9 +394,14 @@ dmq_init(int send_timeout, int connect_timeout) return; /* Reserve area for our shared state */ +#if PG_VERSION_NUM >= 150000 + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = mtm_dmq_shmem_request; +#else RequestAddinShmemSpace(dmq_shmem_size()); RequestNamedLWLockTranche("dmq", 1); +#endif /* Set up common data for all our workers */ memset(&worker, 0, sizeof(worker)); @@ -402,6 +423,18 @@ dmq_init(int send_timeout, int connect_timeout) shmem_startup_hook = dmq_shmem_startup_hook; } +#if PG_VERSION_NUM >= 150000 +static void +mtm_dmq_shmem_request(void) +{ + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + + RequestAddinShmemSpace(dmq_shmem_size()); + RequestNamedLWLockTranche("dmq", 1); +} +#endif + static Size dmq_toc_size() { @@ -776,7 +809,7 @@ dmq_sender_main(Datum main_arg) switch (conns[conn_id].state) { case Idle: - Assert(false); +// Assert(false); break; /* @@ -875,10 +908,23 @@ dmq_sender_main(Datum main_arg) if (!PQisBusy(conns[conn_id].pgconn)) { int8 mask_pos = conns[conn_id].mask_pos; + PGresult *result = PQgetResult(conns[conn_id].pgconn); - /* - * XXX check here that dmq_receiver_loop not failed? - */ + if (!result) { + mtm_log(ERROR, "[DMQ] PQgetResult returned NULL"); + } + + mtm_log(DmqStateIntermediate, "PQgetResult status: %d", PQresultStatus(result)); + + if (PQresultStatus(result) != PGRES_COPY_BOTH) { + mtm_log(DmqStateFinal, "[DMQ] wrong response from dmq receiver '%s': '%s'; '%s'", + conns[conn_id].receiver_name, + PQresStatus(PQresultStatus(result)), + PQerrorMessage(conns[conn_id].pgconn)); + conns[conn_id].state = Idle; + dmq_state->sconn_cnt[conns[conn_id].mask_pos] = DMQSCONN_DEAD; + break; + } conns[conn_id].state = Active; DeleteWaitEvent(set, event.pos); @@ -1119,7 +1165,11 @@ dmq_handle_message(StringInfo msg, DmqReceiverSlot *my_slot, } else { +#if PG_VERSION_NUM < 150000 res = shm_mq_send(mq_handles[sub.procno], body_len, body, false); +#else + res = shm_mq_send(mq_handles[sub.procno], body_len, body, false, true); +#endif if (res == SHM_MQ_DETACHED) mtm_log(COMMERROR, "[DMQ] queue %d is detached, dropping message (stream=%s)", sub.procno, stream_name); @@ -1443,7 +1493,13 @@ dmq_receiver_loop(PG_FUNCTION_ARGS) extra = dmq_receiver_start_hook(sender_name); /* do not hold globalxmin. XXX: try to carefully release snaps */ - MyPgXact->xmin = InvalidTransactionId; +#if PG_VERSION_NUM < 150000 + MyProc->xmin = InvalidTransactionId; +#else + pg_atomic_write_u64(&MyProc->xmin, InvalidTransactionId); +#endif + dmq_receiver_recreate_mqs(&dmq_state->receivers[receiver_id], + segs, mq_handles); for (;;) { @@ -1623,7 +1679,11 @@ dmq_push(DmqDestinationId dest_id, char *stream_name, char *msg) buf.len, buf.len, buf.data); /* XXX: use sendv instead */ +#if PG_VERSION_NUM < 150000 res = shm_mq_send(dmq_local.mq_outh, buf.len, buf.data, false); +#else + res = shm_mq_send(dmq_local.mq_outh, buf.len, buf.data, false, true); +#endif pfree(buf.data); if (res != SHM_MQ_SUCCESS) mtm_log(ERROR, "[DMQ] dmq_push: can't send to queue"); @@ -1648,7 +1708,11 @@ dmq_push_buffer(DmqDestinationId dest_id, char *stream_name, const void *payload buf.len, buf.len, buf.data); /* XXX: use sendv instead */ +#if PG_VERSION_NUM < 150000 res = shm_mq_send(dmq_local.mq_outh, buf.len, buf.data, false); +#else + res = shm_mq_send(dmq_local.mq_outh, buf.len, buf.data, false, true); +#endif pfree(buf.data); if (res != SHM_MQ_SUCCESS) mtm_log(ERROR, "[DMQ] dmq_push: can't send to queue, status = %d", res); diff --git a/src/global_tx.c b/src/global_tx.c index fff4921515..e5cc6d197f 100644 --- a/src/global_tx.c +++ b/src/global_tx.c @@ -47,6 +47,11 @@ char const *const GlobalTxStatusMnem[] = "GTXAborted" }; +#if PG_VERSION_NUM >= 150000 +static shmem_request_hook_type prev_shmem_request_hook = NULL; +static void mtm_gtx_shmem_request(void); +#endif + int term_cmp(GlobalTxTerm t1, GlobalTxTerm t2) { @@ -153,9 +158,32 @@ GlobalTxAtExit(int code, Datum arg) void MtmGlobalTxInit() +{ +#if PG_VERSION_NUM >= 150000 + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = mtm_gtx_shmem_request; +#else + Size size = 0; + + size = add_size(size, sizeof(gtx_shared_data)); + size = add_size(size, hash_estimate_size(2*MaxConnections, + sizeof(GlobalTx))); + size = MAXALIGN(size); + + RequestAddinShmemSpace(size); + RequestNamedLWLockTranche("mtm-gtx-lock", 1); +#endif +} + +#if PG_VERSION_NUM >= 150000 +static void +mtm_gtx_shmem_request(void) { Size size = 0; + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + size = add_size(size, sizeof(gtx_shared_data)); size = add_size(size, hash_estimate_size(2*MaxConnections, sizeof(GlobalTx))); @@ -164,6 +192,7 @@ MtmGlobalTxInit() RequestAddinShmemSpace(size); RequestNamedLWLockTranche("mtm-gtx-lock", 1); } +#endif void MtmGlobalTxShmemStartup(void) @@ -185,7 +214,7 @@ MtmGlobalTxShmemStartup(void) gtx_shared->lock = &(GetNamedLWLockTranche("mtm-gtx-lock"))->lock; gtx_shared->gid2gtx = ShmemInitHash("gid2gtx", 2*MaxConnections, 2*MaxConnections, - &info, HASH_ELEM); + &info, HASH_ELEM | HASH_STRINGS); LWLockRelease(AddinShmemInitLock); } diff --git a/src/include/compat.h b/src/include/compat.h index a6ffaaa248..349617ebb9 100644 --- a/src/include/compat.h +++ b/src/include/compat.h @@ -1,12 +1,16 @@ #ifndef MTMCOMPAT_H #define MTMCOMPAT_H +#if 0 /* built-in connection pool ported */ /* EE pooler gets rid of static variable */ #ifdef PGPRO_EE #define FeBeWaitSetCompat() (MyProcPort->pqcomm_waitset) #else #define FeBeWaitSetCompat() (FeBeWaitSet) #endif +#else +#define FeBeWaitSetCompat() (FeBeWaitSet) +#endif #ifdef PGPRO_EE /* atx */ #define BeginTransactionBlockCompat() (BeginTransactionBlock(false, NIL)) @@ -16,11 +20,6 @@ #define UserAbortTransactionBlockCompat(chain) (UserAbortTransactionBlock(chain)) #endif -/* atx renames this for some reason */ -#ifdef PGPRO_EE -#define on_commits_compat() (pg_on_commit_actions) -#else #define on_commits_compat() (on_commits) -#endif #endif /* MTMCOMPAT_H */ diff --git a/src/multimaster.c b/src/multimaster.c index 9165492afc..ff6fc73e77 100644 --- a/src/multimaster.c +++ b/src/multimaster.c @@ -52,6 +52,8 @@ #include "compat.h" +#include "time.h" + typedef enum { MTM_STATE_LOCK_ID @@ -220,6 +222,10 @@ bool mtm_config_valid; static shmem_startup_hook_type PreviousShmemStartupHook; +#if PG_VERSION_NUM >= 150000 +static shmem_request_hook_type prev_shmem_request_hook = NULL; +static void mtm_shmem_request(void); +#endif /* * If you get really bored one day, you may try hardware-accelerated popcount @@ -711,13 +717,20 @@ NULL); NULL); } + MarkGUCPrefixReserved("multimaster"); + /* * Request additional shared resources. (These are no-ops if we're not in * the postmaster process.) We'll allocate or attach to the shared * resources in mtm_shmem_startup(). */ +#if PG_VERSION_NUM >= 150000 + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = mtm_shmem_request; +#else RequestAddinShmemSpace(MTM_SHMEM_SIZE + sizeof(MtmTime)); RequestNamedLWLockTranche(MULTIMASTER_NAME, 2); +#endif dmq_init(MtmHeartbeatSendTimeout, MtmConnectTimeout); dmq_receiver_start_hook = MtmOnDmqReceiverConnect; @@ -748,6 +761,18 @@ NULL); #endif } +#if PG_VERSION_NUM >= 150000 +static void +mtm_shmem_request(void) +{ + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + + RequestAddinShmemSpace(MTM_SHMEM_SIZE + sizeof(MtmTime)); + RequestNamedLWLockTranche(MULTIMASTER_NAME, 2); +} +#endif + /* * Module unload callback * @@ -1095,6 +1120,9 @@ mtm_after_node_create(PG_FUNCTION_ARGS) bool conninfo_isnull; int n_nodes; int rc; +#if PG_VERSION_NUM >= 150000 + ParseState *pstate; +#endif Assert(CALLED_AS_TRIGGER(fcinfo)); Assert(TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)); @@ -1135,6 +1163,10 @@ mtm_after_node_create(PG_FUNCTION_ARGS) mtm_log(NodeMgmt, "mtm_after_node_create %d", node_id); +#if PG_VERSION_NUM >= 150000 + pstate = make_parsestate(NULL); +#endif + if (is_self) { /* @@ -1143,11 +1175,19 @@ mtm_after_node_create(PG_FUNCTION_ARGS) */ pub_stmt->pubname = MULTIMASTER_NAME; pub_stmt->for_all_tables = false; +#if PG_VERSION_NUM < 150000 pub_stmt->tables = NIL; +#else + pub_stmt->pubobjects = NIL; +#endif pub_stmt->options = list_make1( makeDefElem("publish", (Node *) makeString(pstrdup("insert, truncate")), -1) ); +#if PG_VERSION_NUM < 150000 CreatePublication(pub_stmt); +#else + CreatePublication(pstate, pub_stmt); +#endif /* liftoff */ MtmMonitorStart(MyDatabaseId, GetUserId()); @@ -1186,7 +1226,11 @@ mtm_after_node_create(PG_FUNCTION_ARGS) client_min_messages = ERROR; log_min_messages = ERROR; +#if PG_VERSION_NUM < 150000 CreateSubscription(cs_stmt, true); +#else + CreateSubscription(pstate, cs_stmt, true); +#endif /* restore log_level's */ client_min_messages = saved_client_min_messages; @@ -1204,6 +1248,9 @@ mtm_after_node_create(PG_FUNCTION_ARGS) origin_name = psprintf(MULTIMASTER_SLOT_PATTERN, node_id); replorigin_create(origin_name); } +#if PG_VERSION_NUM >= 150000 + free_parsestate(pstate); +#endif PG_RETURN_VOID(); } @@ -1344,6 +1391,7 @@ mtm_join_node(PG_FUNCTION_ARGS) /* Await for workers finish and create syncpoints */ PG_TRY(); { + const char *logmsg = "MTM Syncpoint in join_node"; while (!MtmAllApplyWorkersFinished()) MtmSleep(USECS_PER_SEC / 10); @@ -1370,7 +1418,7 @@ mtm_join_node(PG_FUNCTION_ARGS) LogLogicalMessage("S", msg, strlen(msg) + 1, false); replorigin_session_origin = InvalidRepOriginId; } - LogLogicalMessage("S", "", 1, false); + LogLogicalMessage("S", logmsg, strlen(logmsg) + 1, false); } PG_CATCH(); { @@ -1524,7 +1572,11 @@ mtm_ping(PG_FUNCTION_ARGS) "Failed to query mtm.cluster_status on '%s': %s", peer_connstr, msg); } +#if PG_VERSION_NUM < 150000 peer_gen_num = pg_strtouint64(PQgetvalue(res, 0, 0), NULL, 10); +#else + peer_gen_num = strtou64(PQgetvalue(res, 0, 0), NULL, 10); +#endif PQclear(res); PQfinish(conn); if (curr_gen.num != peer_gen_num) @@ -1993,7 +2045,13 @@ gather(nodemask_t participants, gather_hook_t msg_ok, Datum msg_ok_arg, int *sendconn_cnt, uint64 gen_num) { + time_t start; + bool to = false; *msg_count = 0; + + start = time(NULL); + + //elog(LOG, "----> gather 1"); while (participants != 0) { bool ret; @@ -2001,6 +2059,15 @@ gather(nodemask_t participants, StringInfoData msg; int rc; bool wait; + time_t current; + + current = time(NULL); + + if (current - start > 3) { + elog(LOG, "----> gather timeout"); + to = true; +// return false; + } ret = dmq_pop_nb(&sender_mask_pos, &msg, participants, &wait); if (ret) @@ -2055,6 +2122,8 @@ gather(nodemask_t participants, } } + if (to) + elog(LOG, "----> gather end"); return true; } diff --git a/src/pglogical_apply.c b/src/pglogical_apply.c index 566d5acb97..3f9c27c2d9 100644 --- a/src/pglogical_apply.c +++ b/src/pglogical_apply.c @@ -172,11 +172,6 @@ create_rel_estate(Relation rel) resultRelInfo = makeNode(ResultRelInfo); InitResultRelInfo(resultRelInfo, rel, 1, NULL, 0); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; - estate->es_result_relation_info = resultRelInfo; - estate->es_output_cid = GetCurrentCommandId(true); - rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; rte->relid = RelationGetRelid(rel); @@ -184,6 +179,9 @@ create_rel_estate(Relation rel) rte->rellockmode = AccessShareLock; ExecInitRangeTable(estate, list_make1(rte)); + estate->es_result_relation_info = resultRelInfo; + estate->es_output_cid = GetCurrentCommandId(true); + /* Prepare to catch AFTER triggers. */ AfterTriggerBeginQuery(); @@ -387,7 +385,7 @@ process_remote_message(StringInfo s, MtmReceiverWorkerContext *rwctx) MtmApplyDDLMessage(messageBody, false); CommitTransactionCommand(); - pgstat_report_activity(STATE_RUNNING, NULL); + pgstat_report_activity(STATE_IDLE, ""); standalone = true; break; } @@ -398,7 +396,7 @@ process_remote_message(StringInfo s, MtmReceiverWorkerContext *rwctx) pfree(activity); mtm_log(MtmApplyMessage, "executing tx DDL message %s", messageBody); MtmApplyDDLMessage(messageBody, true); - pgstat_report_activity(STATE_RUNNING, NULL); + pgstat_report_activity(STATE_IDLE, ""); break; } case 'L': @@ -1238,9 +1236,10 @@ process_remote_insert(StringInfo s, Relation rel) if (relinfo->ri_NumIndices > 0) { List *recheckIndexes; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; - recheckIndexes = ExecInsertIndexTuples(bufferedSlots[i], - estate, false, NULL, NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, bufferedSlots[i], + estate, false, false, NULL, NIL); /* AFTER ROW INSERT Triggers */ ExecARInsertTriggers(estate, relinfo, bufferedSlots[i], @@ -1267,11 +1266,12 @@ process_remote_insert(StringInfo s, Relation rel) else { TupleTableSlot *newslot; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; newslot = ExecInitExtraTupleSlot(estate, tupDesc, &TTSOpsHeapTuple); tuple_to_slot(estate, rel, &new_tuple, newslot); - ExecSimpleRelationInsert(estate, newslot); + ExecSimpleRelationInsert(resultRelInfo, estate, newslot); } ExecCloseIndices(estate->es_result_relation_info); if (ActiveSnapshotSet()) @@ -1367,6 +1367,7 @@ process_remote_update(StringInfo s, Relation rel) if (found) { HeapTuple remote_tuple = NULL; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; remote_tuple = heap_modify_tuple(ExecFetchSlotHeapTuple(localslot, true, NULL), tupDesc, @@ -1376,7 +1377,7 @@ process_remote_update(StringInfo s, Relation rel) ExecStoreHeapTuple(remote_tuple, remoteslot, false); EvalPlanQualSetSlot(&epqstate, remoteslot); - ExecSimpleRelationUpdate(estate, &epqstate, localslot, remoteslot); + ExecSimpleRelationUpdate(resultRelInfo, estate, &epqstate, localslot, remoteslot); } else { @@ -1444,8 +1445,10 @@ process_remote_delete(StringInfo s, Relation rel) if (found) { + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + EvalPlanQualSetSlot(&epqstate, localslot); - ExecSimpleRelationDelete(estate, &epqstate, localslot); + ExecSimpleRelationDelete(resultRelInfo, estate, &epqstate, localslot); } else { diff --git a/src/pglogical_config.c b/src/pglogical_config.c index 0c06660aca..192ef14625 100644 --- a/src/pglogical_config.c +++ b/src/pglogical_config.c @@ -24,7 +24,9 @@ #include "nodes/makefuncs.h" #include "utils/builtins.h" +#if PG_VERSION_NUM < 150000 #include "utils/int8.h" +#endif #include "utils/inval.h" #include "utils/varlena.h" #include "utils/lsyscache.h" @@ -378,6 +380,7 @@ parse_param_bool(DefElem *elem) static uint32 parse_param_uint32(DefElem *elem) { +#if PG_VERSION_NUM < 150000 int64 res; if (!scanint8(strVal(elem->arg), true, &res)) @@ -385,6 +388,18 @@ parse_param_uint32(DefElem *elem) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), MTM_ERRMSG("could not parse integer value \"%s\" for parameter \"%s\"", strVal(elem->arg), elem->defname))); +#else + unsigned long res; + char *endptr; + + errno = 0; + res = strtoul(strVal(elem->arg), &endptr, 10); + if (errno != 0 || *endptr != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + MTM_ERRMSG("could not parse integer value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); +#endif if (res > PG_UINT32_MAX || res < 0) ereport(ERROR, diff --git a/src/pglogical_output.c b/src/pglogical_output.c index 95bfa00540..14bd49130b 100644 --- a/src/pglogical_output.c +++ b/src/pglogical_output.c @@ -44,7 +44,9 @@ #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/guc.h" +#if PG_VERSION_NUM < 150000 #include "utils/int8.h" +#endif #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -70,12 +72,13 @@ static void pg_decode_begin_txn(LogicalDecodingContext *ctx, static void pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn); static void pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn); static void pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn); static void pg_decode_abort_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, - XLogRecPtr lsn); + XLogRecPtr lsn, TimestampTz prepare_time); static bool pg_filter_prepare(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, TransactionId xid, const char *gid); @@ -136,9 +139,10 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->abort_cb = pg_decode_abort_txn; cb->filter_prepare_cb = pg_filter_prepare; + cb->begin_prepare_cb = pg_decode_begin_prepare_txn; cb->prepare_cb = pg_decode_prepare_txn; cb->commit_prepared_cb = pg_decode_commit_prepared_txn; - cb->abort_prepared_cb = pg_decode_abort_prepared_txn; + cb->rollback_prepared_cb = pg_decode_abort_prepared_txn; cb->filter_by_origin_cb = pg_decode_origin_filter; cb->shutdown_cb = pg_decode_shutdown; @@ -485,6 +489,46 @@ pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, } } +void +pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + PGLogicalOutputData *data = (PGLogicalOutputData *) ctx->output_plugin_private; + bool send_replication_origin = data->forward_changeset_origins; + + if (!startup_message_sent) + send_startup_message(ctx, data, false /* can't be last message */ ); + + /* If the record didn't originate locally, send origin info */ + send_replication_origin &= txn->origin_id != InvalidRepOriginId; + + if (data->api) + { + MtmOutputPluginPrepareWrite(ctx, !send_replication_origin, true); + data->api->write_begin(ctx->out, data, txn); + + if (send_replication_origin) + { + char *origin; + + /* Message boundary */ + MtmOutputPluginWrite(ctx, false, false); + MtmOutputPluginPrepareWrite(ctx, true, false); + + /* + * XXX: which behaviour we want here? + * + * Alternatives: - don't send origin message if origin name not + * found (that's what we do now) - throw error - that will break + * replication, not good - send some special "unknown" origin + */ + if (data->api->write_origin && + replorigin_by_oid(txn->origin_id, true, &origin)) + data->api->write_origin(ctx->out, origin, txn->origin_lsn); + } + MtmOutputPluginWrite(ctx, true, false); + } +} + void pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn) @@ -509,7 +553,7 @@ pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn void pg_decode_abort_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, - XLogRecPtr lsn) + XLogRecPtr lsn, TimestampTz prepare_time) { PGLogicalOutputData *data = (PGLogicalOutputData *) ctx->output_plugin_private; diff --git a/src/pglogical_proto.c b/src/pglogical_proto.c index 1c1367fdd4..766f965ae8 100644 --- a/src/pglogical_proto.c +++ b/src/pglogical_proto.c @@ -175,6 +175,7 @@ pglogical_write_begin(StringInfo out, PGLogicalOutputData *data, MtmLastRelId = InvalidOid; MtmCurrentXid = txn->xid; DDLInProgress = false; + elog(LOG, "---> pglogical_write_begin: false"); pq_sendbyte(out, 'B'); /* BEGIN */ pq_sendint(out, hooks_data->cfg->my_node_id, 4); @@ -253,6 +254,7 @@ pglogical_write_message(StringInfo out, LogicalDecodingContext *ctx, case 'D': DDLInProgress = true; + elog(LOG, "---> pglogical_write_message: true %d: %s",hooks_data->receiver_node_id, message); mtm_log(ProtoTraceMessage, "Sent tx DDL message to node %d: %s", hooks_data->receiver_node_id, message); break; @@ -266,6 +268,7 @@ pglogical_write_message(StringInfo out, LogicalDecodingContext *ctx, case 'E': DDLInProgress = false; + elog(LOG, "---> pglogical_write_message: false"); /* * we use End message only as indicator of DDL transaction finish, @@ -468,7 +471,11 @@ pglogical_write_prepare(StringInfo out, PGLogicalOutputData *data, /* send fixed fields */ pq_sendint64(out, lsn); pq_sendint64(out, txn->end_lsn); +#if PG_VERSION_NUM < 150000 pq_sendint64(out, txn->commit_time); +#else + pq_sendint64(out, txn->xact_time.commit_time); +#endif send_node_id(out, txn, hooks_data); pq_sendint64(out, txn->origin_lsn); @@ -499,7 +506,11 @@ pglogical_write_commit_prepared(StringInfo out, PGLogicalOutputData *data, /* send fixed fields */ pq_sendint64(out, lsn); pq_sendint64(out, txn->end_lsn); +#if PG_VERSION_NUM < 150000 pq_sendint64(out, txn->commit_time); +#else + pq_sendint64(out, txn->xact_time.commit_time); +#endif send_node_id(out, txn, hooks_data); pq_sendint64(out, txn->origin_lsn); @@ -532,7 +543,11 @@ pglogical_write_abort_prepared(StringInfo out, PGLogicalOutputData *data, /* send fixed fields */ pq_sendint64(out, lsn); pq_sendint64(out, txn->end_lsn); +#if PG_VERSION_NUM < 150000 pq_sendint64(out, txn->commit_time); +#else + pq_sendint64(out, txn->xact_time.commit_time); +#endif send_node_id(out, txn, hooks_data); pq_sendint64(out, txn->origin_lsn); @@ -560,7 +575,11 @@ pglogical_write_commit(StringInfo out, PGLogicalOutputData *data, /* send fixed fields */ pq_sendint64(out, lsn); pq_sendint64(out, txn->end_lsn); +#if PG_VERSION_NUM < 150000 pq_sendint64(out, txn->commit_time); +#else + pq_sendint64(out, txn->xact_time.commit_time); +#endif send_node_id(out, txn, hooks_data); pq_sendint64(out, txn->origin_lsn); @@ -583,7 +602,11 @@ pglogical_write_abort(StringInfo out, PGLogicalOutputData *data, /* send fixed fields */ pq_sendint64(out, lsn); pq_sendint64(out, txn->end_lsn); +#if PG_VERSION_NUM < 150000 pq_sendint64(out, txn->commit_time); +#else + pq_sendint64(out, txn->xact_time.commit_time); +#endif send_node_id(out, txn, hooks_data); pq_sendint64(out, txn->origin_lsn); diff --git a/src/resolver.c b/src/resolver.c index 2c9933ff51..659e9a2276 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -450,7 +450,7 @@ handle_response(MtmConfig *mtm_cfg, MtmMessage *raw_msg) else if (raw_msg->tag == T_Mtm2AResponse) gid = ((Mtm2AResponse *) raw_msg)->gid; else - Assert(false); + mtm_log(ERROR, "Illegal message tag %d", raw_msg->tag); mtm_log(ResolverTx, "handle_response: got '%s'", MtmMesageToString(raw_msg)); diff --git a/src/state.c b/src/state.c index 01b502b775..a05eb55a74 100644 --- a/src/state.c +++ b/src/state.c @@ -12,6 +12,9 @@ #include #include +#if PG_VERSION_NUM >= 150000 +#include "common/pg_prng.h" +#endif #include "access/twophase.h" #include "access/xlogutils.h" #include "access/xlog_internal.h" @@ -243,6 +246,11 @@ static PrepareBarrierMode pb_acquired_in_mode; static bool campaign_requested; +#if PG_VERSION_NUM >= 150000 +static shmem_request_hook_type prev_shmem_request_hook = NULL; +static void mtm_state_shmem_request(void); +#endif + /* * ----------------------------------- * Startup @@ -252,9 +260,26 @@ static bool campaign_requested; void MtmStateInit() { +#if PG_VERSION_NUM >= 150000 + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = mtm_state_shmem_request; +#else + RequestAddinShmemSpace(sizeof(struct MtmState)); + RequestNamedLWLockTranche("mtm_state_locks", 3); +#endif +} + +#if PG_VERSION_NUM >= 150000 +static void +mtm_state_shmem_request(void) +{ + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + RequestAddinShmemSpace(sizeof(struct MtmState)); RequestNamedLWLockTranche("mtm_state_locks", 3); } +#endif void MtmStateShmemStartup() @@ -1677,7 +1702,11 @@ CampaignerMain(Datum main_arg) MemoryContext campaigner_ctx = AllocSetContextCreate(TopMemoryContext, "CampaignerContext", ALLOCSET_DEFAULT_SIZES); +#if PG_VERSION_NUM < 150000 static unsigned short drandom_seed[3] = {0, 0, 0}; +#else + static pg_prng_state drandom_seed = {0, 0}; +#endif TimestampTz last_campaign_at = 0; int rc = WL_TIMEOUT; @@ -1719,9 +1748,13 @@ CampaignerMain(Datum main_arg) /* Mix the PID with the most predictable bits of the timestamp */ iseed = (uint64) now ^ ((uint64) MyProcPid << 32); +#if PG_VERSION_NUM < 150000 drandom_seed[0] = (unsigned short) iseed; drandom_seed[1] = (unsigned short) (iseed >> 16); drandom_seed[2] = (unsigned short) (iseed >> 32); +#else + pg_prng_seed(&drandom_seed, iseed); +#endif } /* @@ -1801,10 +1834,17 @@ CampaignerMain(Datum main_arg) * here nodes will mostly propose the same set of candidates, * supporting each other) */ +#if PG_VERSION_NUM < 150000 rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, campaign_retry_interval * pg_erand48(drandom_seed), PG_WAIT_EXTENSION); +#else + rc = WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + campaign_retry_interval * pg_prng_double(&drandom_seed), + PG_WAIT_EXTENSION); +#endif if (rc & WL_LATCH_SET) ResetLatch(MyLatch); @@ -3286,7 +3326,7 @@ check_status_requests(MtmConfig *mtm_cfg, bool *job_pending) txset_hash_ctl.entrysize = sizeof(txset_entry); txset_hash_ctl.hcxt = CurrentMemoryContext; txset = hash_create("txset", max_batch_size, &txset_hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); while (dmq_pop_nb(&sender_mask_pos, &packed_msg, MtmGetDmqReceiversMask(), &wait)) { @@ -3729,17 +3769,20 @@ start_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) if (!MtmNodeById(new_cfg, node_id)->init_done) { + ReplicationSlot *s; + /* * Create filter slot to filter out already applied changes since the * last syncpoint during replication start */ /* slot might be already created if we failed before setting init_done */ - int acq = ReplicationSlotAcquire(filter_slot, SAB_Inquire); - if (acq == 0) - ReplicationSlotRelease(); - else if (acq == -1) + + s = SearchNamedReplicationSlot(filter_slot, true); + if (s == NULL) { - ReplicationSlotCreate(filter_slot, false, RS_PERSISTENT); + bool two_phase = true; + + ReplicationSlotCreate(filter_slot, false, RS_PERSISTENT, two_phase); ReplicationSlotReserveWal(); /* Write this slot to disk */ ReplicationSlotMarkDirty(); @@ -3776,17 +3819,18 @@ start_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) if (!MtmNodeById(new_cfg, node_id)->init_done) { + ReplicationSlot *s; char *query; int rc; /* Create logical slot for our publication to this neighbour */ /* slot might be already created if we failed before setting init_done */ - int acq = ReplicationSlotAcquire(slot, SAB_Inquire); - if (acq == 0) - ReplicationSlotRelease(); - else if (acq == -1) - { - ReplicationSlotCreate(slot, true, RS_EPHEMERAL); + + s = SearchNamedReplicationSlot(slot, true); + if (s == NULL) { + bool two_phase = true; + + ReplicationSlotCreate(slot, true, RS_EPHEMERAL, two_phase); ctx = CreateInitDecodingContext(MULTIMASTER_NAME, NIL, false, /* do not build snapshot */ InvalidXLogRecPtr, @@ -3874,7 +3918,7 @@ stop_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) ReplicationSlotDrop(filter_slot_name, true); /* delete replication origin, was acquired by receiver */ - replorigin_drop(replorigin_by_name(logical_slot, false), true); + replorigin_drop_by_name(logical_slot, false, true); /* * Delete logical slot. It is aquired by walsender, so call with nowait = @@ -4236,7 +4280,11 @@ GetLoggedPreparedXactState(HTAB *txset) XLogRecPtr start_lsn; XLogRecPtr lsn; TimeLineID timeline; +#if PG_VERSION_NUM < 150000 XLogRecPtr end_wal_lsn = GetFlushRecPtr(); +#else + XLogRecPtr end_wal_lsn = GetFlushRecPtr(NULL); +#endif XLogRecPtr end_lsn = end_wal_lsn; int n_trans = hash_get_num_entries(txset); @@ -4414,7 +4462,7 @@ mtm_get_logged_prepared_xact_state(PG_FUNCTION_ARGS) txset_hash_ctl.entrysize = sizeof(txset_entry); txset_hash_ctl.hcxt = CurrentMemoryContext; txset = hash_create("txset", 1, &txset_hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); txse = hash_search(txset, gid, HASH_ENTER, NULL); txse->resp.state.status = GTXInvalid; diff --git a/src/syncpoint.c b/src/syncpoint.c index a70ffc36e9..064e707cd6 100644 --- a/src/syncpoint.c +++ b/src/syncpoint.c @@ -103,8 +103,9 @@ MaybeLogSyncpoint(void) (GetInsertRecPtr() - Mtm->latestSyncpoint >= MtmSyncpointInterval * 1024)) { XLogRecPtr syncpoint_lsn; + const char *msg = "MTM syncpoint in MaybeLogsyncpoint"; - syncpoint_lsn = LogLogicalMessage("S", "", 1, false); + syncpoint_lsn = LogLogicalMessage("S", msg, strlen(msg) + 1, false); Mtm->latestSyncpoint = syncpoint_lsn; mtm_log(SyncpointCreated, @@ -144,6 +145,7 @@ SyncpointRegister(int origin_node_id, XLogRecPtr origin_lsn, { char *sql; int rc; + const char *msg = "MTM Syncpoint in SyncpointRegister"; /* Start tx */ StartTransactionCommand(); @@ -156,7 +158,7 @@ SyncpointRegister(int origin_node_id, XLogRecPtr origin_lsn, * performed instead of 3PC and so receiver is not allowed to fail * applying this transaction and go ahead even in normal mode. */ - LogLogicalMessage("B", "", 1, true); + LogLogicalMessage("B", msg, strlen(msg) + 1, true); /* Save syncpoint */ sql = psprintf("insert into mtm.syncpoints values " @@ -477,7 +479,11 @@ RecoveryFilterLoad(int filter_node_id, Syncpoint *spvector, MtmConfig *mtm_cfg) /* ensure we will scan everything written up to this point, just in case */ XLogFlush(GetXLogWriteRecPtr()); +#if PG_VERSION_NUM < 150000 current_last_lsn = GetFlushRecPtr(); +#else + current_last_lsn = GetFlushRecPtr(NULL); +#endif Assert(current_last_lsn != InvalidXLogRecPtr); @@ -490,7 +496,11 @@ RecoveryFilterLoad(int filter_node_id, Syncpoint *spvector, MtmConfig *mtm_cfg) } /* create hash */ +#if PG_VERSION_NUM < 150000 estimate_size = (GetFlushRecPtr() - start_lsn) / 100; +#else + estimate_size = (GetFlushRecPtr(NULL) - start_lsn) / 100; +#endif estimate_size = Min(Max(estimate_size, 1000), 100000); MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = hash_ctl.entrysize = sizeof(FilterEntry); diff --git a/t/000_deadlock.pl b/t/000_deadlock.pl index d22c562baa..78c324961c 100644 --- a/t/000_deadlock.pl +++ b/t/000_deadlock.pl @@ -4,7 +4,6 @@ use warnings; use Cluster; -use TestLib; # Test whether we have both DBI and DBD::pg my $dbdpg_rc = eval diff --git a/t/001_regress.pl b/t/001_regress.pl index cbe1feaaa0..e9d4541e77 100644 --- a/t/001_regress.pl +++ b/t/001_regress.pl @@ -34,7 +34,14 @@ } # determenistic ports for expected files -$PostgresNode::last_port_assigned = 55431; +if ($Cluster::pg_15_modules) +{ + $PostgreSQL::Test::Cluster::last_port_assigned = 55431; +} +else +{ + $PostgresNode::last_port_assigned = 55431; +} my $cluster = new Cluster(3); $cluster->init(q{ @@ -68,10 +75,6 @@ CREATE VIEW pg_prepared_xacts AS select * from _pg_prepared_xacts where gid not like 'MTM-%' ORDER BY transaction::text::bigint; - ALTER TABLE pg_publication RENAME TO _pg_publication; - CREATE VIEW pg_catalog.pg_publication AS SELECT * FROM pg_catalog._pg_publication WHERE pubname<>'multimaster'; - ALTER TABLE pg_subscription RENAME TO _pg_subscription; - CREATE VIEW pg_catalog.pg_subscription AS SELECT * FROM pg_catalog._pg_subscription WHERE subname NOT LIKE 'mtm_sub_%'; }); $cluster->{nodes}->[0]->safe_psql('regression', q{ @@ -84,13 +87,30 @@ # load schedule without tablespace test which is not expected # to work with several postgreses on a single node -my $schedule = TestLib::slurp_file('../../src/test/regress/parallel_schedule'); +my $schedule; +if ($Cluster::pg_15_modules) +{ + $schedule = PostgreSQL::Test::Utils::slurp_file('../../src/test/regress/parallel_schedule'); +} +else +{ + $schedule = TestLib::slurp_file('../../src/test/regress/parallel_schedule'); +} $schedule =~ s/test: tablespace/#test: tablespace/g; $schedule =~ s/test: cfs/#test: cfs/g; $schedule =~ s/test: largeobject//; # serial schedule $schedule =~ s/largeobject//; # parallel schedule +$schedule =~ s/atx0//; # parallel schedule +$schedule =~ s/atx2//; # parallel schedule unlink('parallel_schedule'); -TestLib::append_to_file('parallel_schedule', $schedule); +if ($Cluster::pg_15_modules) +{ + PostgreSQL::Test::Utils::append_to_file('parallel_schedule', $schedule); +} +else +{ + TestLib::append_to_file('parallel_schedule', $schedule); +} my $regress_shlib = $ENV{REGRESS_SHLIB}; my $regress_libdir = dirname($regress_shlib); @@ -99,13 +119,26 @@ # REMOVEME: not needed in 14+, pg_regress fixed in upstream mkdir("${regress_outdir}/sql"); mkdir("${regress_outdir}/expected"); -TestLib::system_log($ENV{'PG_REGRESS'}, - '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, - '--use-existing', '--bindir=', - '--schedule=parallel_schedule', - "--dlpath=${regress_libdir}", - '--inputdir=../../src/test/regress', - "--outputdir=${regress_outdir}"); +if ($Cluster::pg_15_modules) +{ + PostgreSQL::Test::Utils::system_log($ENV{'PG_REGRESS'}, + '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, + '--use-existing', '--bindir=', + '--schedule=parallel_schedule', + "--dlpath=${regress_libdir}", + '--inputdir=../../src/test/regress', + "--outputdir=${regress_outdir}"); +} +else +{ + TestLib::system_log($ENV{'PG_REGRESS'}, + '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, + '--use-existing', '--bindir=', + '--schedule=parallel_schedule', + "--dlpath=${regress_libdir}", + '--inputdir=../../src/test/regress', + "--outputdir=${regress_outdir}"); +} unlink('parallel_schedule'); # rename s/diffs/diff as some upper level testing systems are searching for all @@ -114,7 +147,15 @@ or die "cannot rename file: $!"; # strip absolute paths and dates out of resulted regression.diffs -my $res_diff = TestLib::slurp_file("${regress_outdir}/regression.diff"); +my $res_diff; +if ($Cluster::pg_15_modules) +{ + $res_diff = PostgreSQL::Test::Utils::slurp_file("${regress_outdir}/regression.diff"); +} +else +{ + $res_diff = TestLib::slurp_file("${regress_outdir}/regression.diff"); +} # In <= 11 default diff format was context, since 12 unified; handing lines # starting with ---|+++|*** covers both. # To make someone's life easier, we prepend .. to make relative paths correct. @@ -125,6 +166,9 @@ # diff -U3 /blabla/contrib/mmts/../../src/test/regress/expected/opr_sanity.out /blabla/mmts/../../src/test/regress/results/opr_sanity.out # was added to each file diff $res_diff =~ s/(diff ).+contrib\/mmts(.+\.out).+contrib\/mmts(.+\.out\n)/$1..$2 ..$3/g; +# Since 15 paths are more canonicalized removing '..' if possible +$res_diff =~ s/(--- |\+\+\+ |\*\*\* ).+(\/src\/test\/regress\/expected\/.+\.out)\t.+\n/$1..\/..\/..$2\tCENSORED\n/g; +$res_diff =~ s/(diff ).+(\/src\/test\/regress\/expected\/.+\.out).+contrib\/mmts(.+\.out\n)/$1..\/..\/..$2 ..$3/g; $res_diff =~ s/(lo_import[ \(]')\/[^']+\//$1\/CENSORED\//g; #SELECT lo_export(loid, '/home/alex/projects/ppro/postgrespro/contrib/mmts/../../src/test/regress/results/lotest.txt') FROM lotest_stash_values; $res_diff =~ s/(lo_export.*\'\/).+\//$1CENSORED\//g; @@ -134,7 +178,14 @@ # finally compare regression.diffs with our version # Do not use diffs extension as some upper level testing systems are searching for all # *.diffs files. -TestLib::append_to_file("$ENV{TESTDIR}/results/regression.diff", $res_diff); +if ($Cluster::pg_15_modules) +{ + PostgreSQL::Test::Utils::append_to_file("$ENV{TESTDIR}/results/regression.diff", $res_diff); +} +else +{ + TestLib::append_to_file("$ENV{TESTDIR}/results/regression.diff", $res_diff); +} # TODO: work with diffs on per-test basis my $expected_file; if (Cluster::is_ee()) @@ -145,7 +196,19 @@ { $expected_file = "expected/regression_vanilla.diff" } -$diff = TestLib::system_log("diff -U3 ${expected_file} $ENV{TESTDIR}/results/regression.diff"); +# Remove lines which contains random data (like ports, users, etc) from output file +# Remove line which starts with '+ mtm_sub_' from output file because it contains random user +run [ "sed", "-i.bak.000", "/+ mtm_sub_/d", "$ENV{TESTDIR}/results/regression.diff" ]; +# Remove line which starts from '+ multimaster' from output file because it contains random port number +run [ "sed", "-i.bak.001", "/+ multimaster/d", "$ENV{TESTDIR}/results/regression.diff" ]; +if ($Cluster::pg_15_modules) +{ + $diff = PostgreSQL::Test::Utils::system_log("diff -U3 ${expected_file} $ENV{TESTDIR}/results/regression.diff"); +} +else +{ + $diff = TestLib::system_log("diff -U3 ${expected_file} $ENV{TESTDIR}/results/regression.diff"); +} run [ "diff", "-U3", "${expected_file}", "$ENV{TESTDIR}/results/regression.diff" ], ">", "$ENV{TESTDIR}/regression.diff.diff"; my $res = $?; diff --git a/t/002_regressmm.pl b/t/002_regressmm.pl index 43af034318..f02286feda 100644 --- a/t/002_regressmm.pl +++ b/t/002_regressmm.pl @@ -3,7 +3,14 @@ use Test::More tests => 1; # determenistic ports for expected files -$PostgresNode::last_port_assigned = 55431; +if ($Cluster::pg_15_modules) +{ + $PostgreSQL::Test::Cluster::last_port_assigned = 55431; +} +else +{ + $PostgresNode::last_port_assigned = 55431; +} my $cluster = new Cluster(3); $cluster->init(q{ @@ -23,11 +30,25 @@ push @tests, 'atx'; } -my $ret = TestLib::system_log($ENV{'PG_REGRESS'}, - '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, - '--use-existing', '--bindir=', @tests); -if ($ret != 0) +my $ret; +if ($Cluster::pg_15_modules) +{ + $ret = PostgreSQL::Test::Utils::system_log($ENV{'PG_REGRESS'}, + '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, + '--use-existing', '--bindir=', @tests); + if ($ret != 0) + { + print "### Got regression! \n", PostgreSQL::Test::Utils::slurp_file('regression.diffs'); + } +} +else { - print "### Got regression! \n", TestLib::slurp_file('regression.diffs'); + $ret = TestLib::system_log($ENV{'PG_REGRESS'}, + '--host=' . $cluster->{nodes}->[0]->host, '--port=' . $cluster->{nodes}->[0]->port, + '--use-existing', '--bindir=', @tests); + if ($ret != 0) + { + print "### Got regression! \n", TestLib::slurp_file('regression.diffs'); + } } is($ret, 0, "multimaster regress"); diff --git a/t/003_basic_recovery.pl b/t/003_basic_recovery.pl index ea8fb37e1f..7826984e5f 100644 --- a/t/003_basic_recovery.pl +++ b/t/003_basic_recovery.pl @@ -4,7 +4,6 @@ use strict; use warnings; use Cluster; -use TestLib; use Test::More tests => 4; my $cluster = new Cluster(3); diff --git a/t/004_recovery.pl b/t/004_recovery.pl index e551e25ea8..b7268c1dc9 100644 --- a/t/004_recovery.pl +++ b/t/004_recovery.pl @@ -2,7 +2,6 @@ use warnings; use Cluster; -use TestLib; use Test::More tests => 6; my $cluster = new Cluster(3); diff --git a/t/005_pgbench.pl b/t/005_pgbench.pl index 18f8d777e0..0704d4b537 100644 --- a/t/005_pgbench.pl +++ b/t/005_pgbench.pl @@ -5,7 +5,6 @@ use warnings; use Cluster; -use TestLib; use Test::More tests => 2; my $cluster = new Cluster(2); diff --git a/t/006_pgbenchdl.pl b/t/006_pgbenchdl.pl index 4f51d1c4c7..1b2cfe1bf8 100644 --- a/t/006_pgbenchdl.pl +++ b/t/006_pgbenchdl.pl @@ -5,7 +5,6 @@ use warnings; use Cluster; -use TestLib; use Test::More tests => 1; use Data::Dumper; diff --git a/t/007_add_stop_node.pl b/t/007_add_stop_node.pl index 97dbbf677a..4c896fd73d 100644 --- a/t/007_add_stop_node.pl +++ b/t/007_add_stop_node.pl @@ -2,9 +2,7 @@ use warnings; use Carp; -use PostgresNode; use Cluster; -use TestLib; use Test::More tests => 8; # Generally add node with concurrent load (and failures) is not supported diff --git a/t/008_bugfixes.pl b/t/008_bugfixes.pl index 21824abc47..e0a8252e9f 100644 --- a/t/008_bugfixes.pl +++ b/t/008_bugfixes.pl @@ -2,11 +2,9 @@ use POSIX; use strict; use Test::More; -use TestLib; use Time::HiRes qw(usleep); use warnings; -use PostgresNode; use Cluster; use Test::More tests => Cluster::is_ee() ? 6 : 5; diff --git a/t/009_identity_func.pl b/t/009_identity_func.pl index 7d159c3aed..b15b78acff 100644 --- a/t/009_identity_func.pl +++ b/t/009_identity_func.pl @@ -1,8 +1,6 @@ use strict; use warnings; -use PostgresNode; use Cluster; -use TestLib; use Test::More tests => 29; my $cluster = new Cluster(3); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy