mirror of https://github.com/postgres/postgres
This reverts a sequence of commits, implementing features related to logical decoding and replication of sequences: -pull/81/head0da92dc530
-80901b3291
-b779d7d8fd
-d5ed9da41d
-a180c2b34d
-75b1521dae
-2d2232933b
-002c9dd97a
-05843b1aa4
The implementation has issues, mostly due to combining transactional and non-transactional behavior of sequences. It's not clear how this could be fixed, but it'll require reworking significant part of the patch. Discussion: https://postgr.es/m/95345a19-d508-63d1-860a-f5c2f41e8d40@enterprisedb.com
parent
d7ab2a9a3c
commit
2c7ea57e56
File diff suppressed because one or more lines are too long
@ -1,325 +0,0 @@ |
||||
-- predictability |
||||
SET synchronous_commit = on; |
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); |
||||
?column? |
||||
---------- |
||||
init |
||||
(1 row) |
||||
|
||||
CREATE SEQUENCE test_sequence; |
||||
-- test the sequence changes by several nextval() calls |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
1 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
2 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
4 |
||||
(1 row) |
||||
|
||||
-- test the sequence changes by several ALTER commands |
||||
ALTER SEQUENCE test_sequence INCREMENT BY 10; |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
14 |
||||
(1 row) |
||||
|
||||
ALTER SEQUENCE test_sequence START WITH 3000; |
||||
ALTER SEQUENCE test_sequence MAXVALUE 10000; |
||||
ALTER SEQUENCE test_sequence RESTART WITH 4000; |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
4000 |
||||
(1 row) |
||||
|
||||
-- test the sequence changes by several setval() calls |
||||
SELECT setval('test_sequence', 3500); |
||||
setval |
||||
-------- |
||||
3500 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3510 |
||||
(1 row) |
||||
|
||||
SELECT setval('test_sequence', 3500, true); |
||||
setval |
||||
-------- |
||||
3500 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3510 |
||||
(1 row) |
||||
|
||||
SELECT setval('test_sequence', 3500, false); |
||||
setval |
||||
-------- |
||||
3500 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3500 |
||||
(1 row) |
||||
|
||||
-- show results and drop sequence |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
---------------------------------------------------------------------------------------- |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 1 log_cnt: 0 is_called:0 |
||||
COMMIT |
||||
sequence public.test_sequence: transactional:0 last_value: 33 log_cnt: 0 is_called:1 |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 4 log_cnt: 0 is_called:1 |
||||
COMMIT |
||||
sequence public.test_sequence: transactional:0 last_value: 334 log_cnt: 0 is_called:1 |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 14 log_cnt: 32 is_called:1 |
||||
COMMIT |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 14 log_cnt: 0 is_called:1 |
||||
COMMIT |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 4000 log_cnt: 0 is_called:0 |
||||
COMMIT |
||||
sequence public.test_sequence: transactional:0 last_value: 4320 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:0 last_value: 3830 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:0 last_value: 3830 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:0 |
||||
sequence public.test_sequence: transactional:0 last_value: 3820 log_cnt: 0 is_called:1 |
||||
(24 rows) |
||||
|
||||
DROP SEQUENCE test_sequence; |
||||
-- rollback on sequence creation and update |
||||
BEGIN; |
||||
CREATE SEQUENCE test_sequence; |
||||
CREATE TABLE test_table (a INT); |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
1 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
2 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3 |
||||
(1 row) |
||||
|
||||
SELECT setval('test_sequence', 3000); |
||||
setval |
||||
-------- |
||||
3000 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3001 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3002 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3003 |
||||
(1 row) |
||||
|
||||
ALTER SEQUENCE test_sequence RESTART WITH 6000; |
||||
INSERT INTO test_table VALUES( (SELECT nextval('test_sequence')) ); |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
6001 |
||||
(1 row) |
||||
|
||||
ROLLBACK; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
------ |
||||
(0 rows) |
||||
|
||||
-- rollback on table creation with serial column |
||||
BEGIN; |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
SELECT setval('test_table_a_seq', 3000); |
||||
setval |
||||
-------- |
||||
3000 |
||||
(1 row) |
||||
|
||||
INSERT INTO test_table (b) VALUES (400); |
||||
INSERT INTO test_table (b) VALUES (500); |
||||
INSERT INTO test_table (b) VALUES (600); |
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000; |
||||
INSERT INTO test_table (b) VALUES (700); |
||||
INSERT INTO test_table (b) VALUES (800); |
||||
INSERT INTO test_table (b) VALUES (900); |
||||
ROLLBACK; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
------ |
||||
(0 rows) |
||||
|
||||
-- rollback on table with serial column |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
BEGIN; |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
SELECT setval('test_table_a_seq', 3000); |
||||
setval |
||||
-------- |
||||
3000 |
||||
(1 row) |
||||
|
||||
INSERT INTO test_table (b) VALUES (400); |
||||
INSERT INTO test_table (b) VALUES (500); |
||||
INSERT INTO test_table (b) VALUES (600); |
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000; |
||||
INSERT INTO test_table (b) VALUES (700); |
||||
INSERT INTO test_table (b) VALUES (800); |
||||
INSERT INTO test_table (b) VALUES (900); |
||||
ROLLBACK; |
||||
-- check table and sequence values after rollback |
||||
SELECT * from test_table_a_seq; |
||||
last_value | log_cnt | is_called |
||||
------------+---------+----------- |
||||
3003 | 30 | t |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_table_a_seq'); |
||||
nextval |
||||
--------- |
||||
3004 |
||||
(1 row) |
||||
|
||||
DROP TABLE test_table; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
------------------------------------------------------------------------------------------- |
||||
BEGIN |
||||
sequence public.test_table_a_seq: transactional:1 last_value: 1 log_cnt: 0 is_called:0 |
||||
COMMIT |
||||
sequence public.test_table_a_seq: transactional:0 last_value: 33 log_cnt: 0 is_called:1 |
||||
sequence public.test_table_a_seq: transactional:0 last_value: 3000 log_cnt: 0 is_called:1 |
||||
sequence public.test_table_a_seq: transactional:0 last_value: 3033 log_cnt: 0 is_called:1 |
||||
(6 rows) |
||||
|
||||
-- savepoint test on table with serial column |
||||
BEGIN; |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
SAVEPOINT a; |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
ROLLBACK TO SAVEPOINT a; |
||||
DROP TABLE test_table; |
||||
COMMIT; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
----------------------------------------------------------------------------------------- |
||||
BEGIN |
||||
sequence public.test_table_a_seq: transactional:1 last_value: 1 log_cnt: 0 is_called:0 |
||||
sequence public.test_table_a_seq: transactional:1 last_value: 33 log_cnt: 0 is_called:1 |
||||
table public.test_table: INSERT: a[integer]:1 b[integer]:100 |
||||
table public.test_table: INSERT: a[integer]:2 b[integer]:200 |
||||
COMMIT |
||||
(6 rows) |
||||
|
||||
-- savepoint test on table with serial column |
||||
BEGIN; |
||||
CREATE SEQUENCE test_sequence; |
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
1 |
||||
(1 row) |
||||
|
||||
SELECT setval('test_sequence', 3000); |
||||
setval |
||||
-------- |
||||
3000 |
||||
(1 row) |
||||
|
||||
SELECT nextval('test_sequence'); |
||||
nextval |
||||
--------- |
||||
3001 |
||||
(1 row) |
||||
|
||||
SAVEPOINT a; |
||||
ALTER SEQUENCE test_sequence START WITH 7000; |
||||
SELECT setval('test_sequence', 5000); |
||||
setval |
||||
-------- |
||||
5000 |
||||
(1 row) |
||||
|
||||
ROLLBACK TO SAVEPOINT a; |
||||
SELECT * FROM test_sequence; |
||||
last_value | log_cnt | is_called |
||||
------------+---------+----------- |
||||
3001 | 32 | t |
||||
(1 row) |
||||
|
||||
DROP SEQUENCE test_sequence; |
||||
COMMIT; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
data |
||||
---------------------------------------------------------------------------------------- |
||||
BEGIN |
||||
sequence public.test_sequence: transactional:1 last_value: 1 log_cnt: 0 is_called:0 |
||||
sequence public.test_sequence: transactional:1 last_value: 33 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:1 last_value: 3000 log_cnt: 0 is_called:1 |
||||
sequence public.test_sequence: transactional:1 last_value: 3033 log_cnt: 0 is_called:1 |
||||
COMMIT |
||||
(6 rows) |
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot'); |
||||
pg_drop_replication_slot |
||||
-------------------------- |
||||
|
||||
(1 row) |
||||
|
@ -1,119 +0,0 @@ |
||||
-- predictability |
||||
SET synchronous_commit = on; |
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); |
||||
|
||||
CREATE SEQUENCE test_sequence; |
||||
|
||||
-- test the sequence changes by several nextval() calls |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
|
||||
-- test the sequence changes by several ALTER commands |
||||
ALTER SEQUENCE test_sequence INCREMENT BY 10; |
||||
SELECT nextval('test_sequence'); |
||||
|
||||
ALTER SEQUENCE test_sequence START WITH 3000; |
||||
ALTER SEQUENCE test_sequence MAXVALUE 10000; |
||||
ALTER SEQUENCE test_sequence RESTART WITH 4000; |
||||
SELECT nextval('test_sequence'); |
||||
|
||||
-- test the sequence changes by several setval() calls |
||||
SELECT setval('test_sequence', 3500); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT setval('test_sequence', 3500, true); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT setval('test_sequence', 3500, false); |
||||
SELECT nextval('test_sequence'); |
||||
|
||||
-- show results and drop sequence |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
DROP SEQUENCE test_sequence; |
||||
|
||||
-- rollback on sequence creation and update |
||||
BEGIN; |
||||
CREATE SEQUENCE test_sequence; |
||||
CREATE TABLE test_table (a INT); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT setval('test_sequence', 3000); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
SELECT nextval('test_sequence'); |
||||
ALTER SEQUENCE test_sequence RESTART WITH 6000; |
||||
INSERT INTO test_table VALUES( (SELECT nextval('test_sequence')) ); |
||||
SELECT nextval('test_sequence'); |
||||
ROLLBACK; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
|
||||
-- rollback on table creation with serial column |
||||
BEGIN; |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
SELECT setval('test_table_a_seq', 3000); |
||||
INSERT INTO test_table (b) VALUES (400); |
||||
INSERT INTO test_table (b) VALUES (500); |
||||
INSERT INTO test_table (b) VALUES (600); |
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000; |
||||
INSERT INTO test_table (b) VALUES (700); |
||||
INSERT INTO test_table (b) VALUES (800); |
||||
INSERT INTO test_table (b) VALUES (900); |
||||
ROLLBACK; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
|
||||
-- rollback on table with serial column |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
|
||||
BEGIN; |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
SELECT setval('test_table_a_seq', 3000); |
||||
INSERT INTO test_table (b) VALUES (400); |
||||
INSERT INTO test_table (b) VALUES (500); |
||||
INSERT INTO test_table (b) VALUES (600); |
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000; |
||||
INSERT INTO test_table (b) VALUES (700); |
||||
INSERT INTO test_table (b) VALUES (800); |
||||
INSERT INTO test_table (b) VALUES (900); |
||||
ROLLBACK; |
||||
|
||||
-- check table and sequence values after rollback |
||||
SELECT * from test_table_a_seq; |
||||
SELECT nextval('test_table_a_seq'); |
||||
|
||||
DROP TABLE test_table; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
|
||||
-- savepoint test on table with serial column |
||||
BEGIN; |
||||
CREATE TABLE test_table (a SERIAL, b INT); |
||||
INSERT INTO test_table (b) VALUES (100); |
||||
INSERT INTO test_table (b) VALUES (200); |
||||
SAVEPOINT a; |
||||
INSERT INTO test_table (b) VALUES (300); |
||||
ROLLBACK TO SAVEPOINT a; |
||||
DROP TABLE test_table; |
||||
COMMIT; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
|
||||
-- savepoint test on table with serial column |
||||
BEGIN; |
||||
CREATE SEQUENCE test_sequence; |
||||
SELECT nextval('test_sequence'); |
||||
SELECT setval('test_sequence', 3000); |
||||
SELECT nextval('test_sequence'); |
||||
SAVEPOINT a; |
||||
ALTER SEQUENCE test_sequence START WITH 7000; |
||||
SELECT setval('test_sequence', 5000); |
||||
ROLLBACK TO SAVEPOINT a; |
||||
SELECT * FROM test_sequence; |
||||
DROP SEQUENCE test_sequence; |
||||
COMMIT; |
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); |
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot'); |
File diff suppressed because it is too large
Load Diff
@ -1,202 +0,0 @@ |
||||
|
||||
# Copyright (c) 2021, PostgreSQL Global Development Group |
||||
|
||||
# This tests that sequences are replicated correctly by logical replication |
||||
use strict; |
||||
use warnings; |
||||
use PostgreSQL::Test::Cluster; |
||||
use PostgreSQL::Test::Utils; |
||||
use Test::More; |
||||
|
||||
# Initialize publisher node |
||||
my $node_publisher = PostgreSQL::Test::Cluster->new('publisher'); |
||||
$node_publisher->init(allows_streaming => 'logical'); |
||||
$node_publisher->start; |
||||
|
||||
# Create subscriber node |
||||
my $node_subscriber = PostgreSQL::Test::Cluster->new('subscriber'); |
||||
$node_subscriber->init(allows_streaming => 'logical'); |
||||
$node_subscriber->start; |
||||
|
||||
# Create some preexisting content on publisher |
||||
my $ddl = qq( |
||||
CREATE TABLE seq_test (v BIGINT); |
||||
CREATE SEQUENCE s; |
||||
); |
||||
|
||||
# Setup structure on the publisher |
||||
$node_publisher->safe_psql('postgres', $ddl); |
||||
|
||||
# Create some the same structure on subscriber, and an extra sequence that |
||||
# we'll create on the publisher later |
||||
$ddl = qq( |
||||
CREATE TABLE seq_test (v BIGINT); |
||||
CREATE SEQUENCE s; |
||||
CREATE SEQUENCE s2; |
||||
); |
||||
|
||||
$node_subscriber->safe_psql('postgres', $ddl); |
||||
|
||||
# Setup logical replication |
||||
my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; |
||||
$node_publisher->safe_psql('postgres', |
||||
"CREATE PUBLICATION seq_pub"); |
||||
|
||||
$node_publisher->safe_psql('postgres', |
||||
"ALTER PUBLICATION seq_pub ADD SEQUENCE s"); |
||||
|
||||
$node_subscriber->safe_psql('postgres', |
||||
"CREATE SUBSCRIPTION seq_sub CONNECTION '$publisher_connstr' PUBLICATION seq_pub" |
||||
); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Wait for initial sync to finish as well |
||||
my $synced_query = |
||||
"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; |
||||
$node_subscriber->poll_query_until('postgres', $synced_query) |
||||
or die "Timed out while waiting for subscriber to synchronize data"; |
||||
|
||||
# Insert initial test data |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
-- generate a number of values using the sequence |
||||
INSERT INTO seq_test SELECT nextval('s') FROM generate_series(1,100); |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Check the data on subscriber |
||||
my $result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s; |
||||
)); |
||||
|
||||
is( $result, '132|0|t', |
||||
'initial test data replicated'); |
||||
|
||||
|
||||
# advance the sequence in a rolled-back transaction - the rollback |
||||
# does not wait for the replication, so we could see any intermediate state |
||||
# so do something else after the test, to ensure we wait for everything |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
BEGIN; |
||||
INSERT INTO seq_test SELECT nextval('s') FROM generate_series(1,100); |
||||
ROLLBACK; |
||||
INSERT INTO seq_test VALUES (-1); |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Check the data on subscriber |
||||
$result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s; |
||||
)); |
||||
|
||||
is( $result, '231|0|t', |
||||
'advance sequence in rolled-back transaction'); |
||||
|
||||
|
||||
# create a new sequence and roll it back - should not be replicated, due to |
||||
# the transactional behavior |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
BEGIN; |
||||
CREATE SEQUENCE s2; |
||||
ALTER PUBLICATION seq_pub ADD SEQUENCE s2; |
||||
INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); |
||||
ROLLBACK; |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Check the data on subscriber |
||||
$result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s2; |
||||
)); |
||||
|
||||
is( $result, '1|0|f', |
||||
'create new sequence and roll it back'); |
||||
|
||||
|
||||
# create a new sequence, advance it in a rolled-back transaction, but commit |
||||
# the create - the advance should be replicated nevertheless |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
BEGIN; |
||||
CREATE SEQUENCE s2; |
||||
ALTER PUBLICATION seq_pub ADD SEQUENCE s2; |
||||
SAVEPOINT sp1; |
||||
INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); |
||||
ROLLBACK TO sp1; |
||||
COMMIT; |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Wait for sync of the second sequence we just added to finish |
||||
$synced_query = |
||||
"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; |
||||
$node_subscriber->poll_query_until('postgres', $synced_query) |
||||
or die "Timed out while waiting for subscriber to synchronize data"; |
||||
|
||||
# Check the data on subscriber |
||||
$result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s2; |
||||
)); |
||||
|
||||
is( $result, '132|0|t', |
||||
'create sequence, advance it in rolled-back transaction, but commit the create'); |
||||
|
||||
|
||||
# advance the new sequence in a transaction, and roll it back - the rollback |
||||
# does not wait for the replication, so we could see any intermediate state |
||||
# so do something else after the test, to ensure we wait for everything |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
BEGIN; |
||||
INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); |
||||
ROLLBACK; |
||||
INSERT INTO seq_test VALUES (-1); |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Check the data on subscriber |
||||
$result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s2; |
||||
)); |
||||
|
||||
is( $result, '231|0|t', |
||||
'advance the new sequence in a transaction and roll it back'); |
||||
|
||||
|
||||
# advance the sequence in a subtransaction - the subtransaction gets rolled |
||||
# back, but commit the main one - the changes should still be replicated |
||||
$node_publisher->safe_psql( |
||||
'postgres', qq( |
||||
BEGIN; |
||||
SAVEPOINT s1; |
||||
INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); |
||||
ROLLBACK TO s1; |
||||
COMMIT; |
||||
)); |
||||
|
||||
$node_publisher->wait_for_catchup('seq_sub'); |
||||
|
||||
# Check the data on subscriber |
||||
$result = $node_subscriber->safe_psql( |
||||
'postgres', qq( |
||||
SELECT * FROM s2; |
||||
)); |
||||
|
||||
is( $result, '330|0|t', |
||||
'advance sequence in a subtransaction'); |
||||
|
||||
|
||||
done_testing(); |
Loading…
Reference in new issue