On 2020-May-15, Michael Paquier wrote: > On Thu, May 14, 2020 at 02:12:25PM +0900, Kyotaro Horiguchi wrote: > > Good catch! That's not only for CreateDecodingContet. That happens > > everywhere in the query loop in PostgresMain() until logreader is > > initialized. So that also happens, for example, by starting logical > > replication using invalidated slot. Checking xlogreader != NULL in > > WalSndErrorCleanup is sufficient. It doesn't make actual difference, > > but the attached explicitly initialize the pointer with NULL. > > Alvaro, are you planning to look at that? Should we have an open item > for this matter?
On it now. I'm trying to add a test for this (needs a small change to PostgresNode->psql), but I'm probably doing something stupid in the Perl side, because it doesn't detect things as well as I'd like. Still trying, but I may be asked to evict the office soon ... -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index 3f3a1d81f6..0645e07789 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -1386,6 +1386,12 @@ the B<timed_out> parameter is also given. If B<timeout> is set and this parameter is given, the scalar it references is set to true if the psql call times out. +=item replication => B<value> + +If set, pass the value as B<replication=value> in the conninfo string. +Passing literal B<database> results in a logical replication connection. +Passing literal B<1> results in a physical replication connection. + =item extra_params => ['--single-transaction'] If given, it must be an array reference containing additional parameters to B<psql>. @@ -1414,10 +1420,14 @@ sub psql my $stdout = $params{stdout}; my $stderr = $params{stderr}; + my $replication = $params{replication}; my $timeout = undef; my $timeout_exception = 'psql timed out'; my @psql_params = - ('psql', '-XAtq', '-d', $self->connstr($dbname), '-f', '-'); + ('psql', '-XAtq', '-d', + $self->connstr($dbname) . + (defined $replication ? " replication=$replication" : ""), + '-f', '-'); # If the caller wants an array and hasn't passed stdout/stderr # references, allocate temporary ones to capture them so we diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl index d40a500ed4..5c7e137e97 100644 --- a/src/test/recovery/t/006_logical_decoding.pl +++ b/src/test/recovery/t/006_logical_decoding.pl @@ -7,7 +7,7 @@ use strict; use warnings; use PostgresNode; use TestLib; -use Test::More tests => 12; +use Test::More tests => 13; use Config; # Initialize master node @@ -27,12 +27,20 @@ $node_master->safe_psql('postgres', qq[SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding');] ); +# Cover walsender error shutdown code +my ($result, $stdout, $stderr) = $node_master->psql('template1', + qq[START_REPLICATION SLOT test_slot LOGICAL 0/0], + replication => 'database'); +ok(($result == 3) and + ($stderr =~ 'replication slot "test_slot" was not created in this database'), + "Logical decoding correctly fails to start"); + $node_master->safe_psql('postgres', qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;] ); # Basic decoding works -my ($result) = $node_master->safe_psql('postgres', +$result = $node_master->safe_psql('postgres', qq[SELECT pg_logical_slot_get_changes('test_slot', NULL, NULL);]); is(scalar(my @foobar = split /^/m, $result), 12, 'Decoding produced 12 rows inc BEGIN/COMMIT');