Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rQWgT-001r6g-JM for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jan 2024 18:00:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rQWgS-004e7d-M9 for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jan 2024 18:00:08 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rQWgS-004e7U-5b for pgsql-hackers@lists.postgresql.org; Thu, 18 Jan 2024 18:00:08 +0000 Received: from mail-lj1-x22f.google.com ([2a00:1450:4864:20::22f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rQWgP-002Bm9-3O for pgsql-hackers@postgresql.org; Thu, 18 Jan 2024 18:00:06 +0000 Received: by mail-lj1-x22f.google.com with SMTP id 38308e7fff4ca-2cceb5f0918so133046271fa.2 for ; Thu, 18 Jan 2024 10:00:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705600803; x=1706205603; darn=postgresql.org; h=subject:from:to:content-language:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=X3VTHmX3va9PvKBS7Tk2Cfvia/HQgpg6OFM4IFOfPqI=; b=MTABhUcm1fTn3GlrlA/v7FoLleNugb346mZdQaJc650NrUiELiBpie4BnOg85Z3Crz QKr5GHZLffjHYYCb+/mI1NvOnRU2FC4aIjKVtyS/eJUGwG0ViDfuGJTIDkwj7c/0O+Y1 d16YN8oVrC6fzWxW19A3W3f5hnwu/6Zt/jPEd8eXGSVt0W42yX/vC5/9r/su/zNxM3nU 9blzGKdfCVtyjjGovgkriR02w2AEhmlNdtLiUJlh4IUKPqLXvGPv1gck3ufFZZdV+24g 69Ea+5SPumoKZoYVxXDC8X1vbfVgCRMMC/NMMCLsOImcfUT1XykmaZS4ce5x8FEDiYeh BXzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705600803; x=1706205603; h=subject:from:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=X3VTHmX3va9PvKBS7Tk2Cfvia/HQgpg6OFM4IFOfPqI=; b=HXfqzJAkWvSy9DG/6ZKyOqiF4p+v26rFPXpRS4u3XWLGXbsHcG9VzAkSDiDlAXUBZc YIyXac7TYaZxi7HOBRGJn3pOsj0/Z+f5Vk9/VLIgKbAaTxp1yJREUIhPdldMhnKza8h5 fxh6zr9OqEZi3+yjdmWWGm+GVXsQB5CPXsLgvaPrrMlguSHJw5ynGBsSUUMIJ9i93JQK McZZ4avgIjibaEZgq2nJ1YiWYFvKzTuKOZXDu/gvmmoA/GOWe64wbmUljKw+l/PYFn+T EFp8US6qQHhoYB3+NGfiSMlu3JrPhN2G9xFS0XF+DQWM6AsJjpjp9Sy/vVT5NtNKtyg2 GAQg== X-Gm-Message-State: AOJu0YwPmNnw+SprJn3pSt3t3rnzCMM8zCSU7Ynao07tud46aGBCsMWI Cjo2vN4AH9tHav5E3sJUVDFDeQjRGWro4yq53MhfJ+nWBsSi+HArE+POs5iu X-Google-Smtp-Source: AGHT+IFBIh+Tfu1icbQAX7ECNjATEjk9qeKuKpIAzqWm326dgoFgji01xHZNm4H2aGDv2eytK0aXrQ== X-Received: by 2002:a19:5e1e:0:b0:50e:e0af:4efd with SMTP id s30-20020a195e1e000000b0050ee0af4efdmr5112lfb.200.1705600803253; Thu, 18 Jan 2024 10:00:03 -0800 (PST) Received: from [1.0.0.7] ([91.185.77.50]) by smtp.gmail.com with ESMTPSA id h13-20020a056512220d00b0050f0a6888f7sm708522lfu.142.2024.01.18.10.00.01 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 18 Jan 2024 10:00:02 -0800 (PST) Content-Type: multipart/mixed; boundary="------------2WjKRzPQvlP7FQoSlkG7Wwg1" Message-ID: Date: Thu, 18 Jan 2024 21:00:01 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Content-Language: en-US To: pgsql-hackers From: Alexander Lakhin Subject: BUG: Former primary node might stuck when started as a standby List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------2WjKRzPQvlP7FQoSlkG7Wwg1 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello hackers, [ reporting this bug here due to limitations of the bug reporting form ] When a node, that acted as a primary, becomes a standby as in the following script: [ ... some WAL-logged activity ... ] $primary->teardown_node; $standby->promote; $primary->enable_streaming($standby); $primary->start; it might not go online, due to the error: new timeline N forked off current database system timeline M before current recovery point X/X A complete TAP test is attached. I put it in src/test/recovery/t, run as follows: for i in `seq 100`; do echo "iteration $i"; timeout 60 make -s check -C src/test/recovery PROVE_TESTS="t/099*" || break; done and get: ... iteration 7 # +++ tap check in src/test/recovery +++ t/099_change_roles.pl .. ok All tests successful. Files=1, Tests=20, 14 wallclock secs ( 0.01 usr  0.00 sys +  4.20 cusr  4.75 csys =  8.96 CPU) Result: PASS iteration 8 # +++ tap check in src/test/recovery +++ t/099_change_roles.pl .. 9/? make: *** [Makefile:23: check] Terminated With wal_debug enabled (and log_min_messages=DEBUG2, log_statement=all), I see the following in the _node1.log: 2024-01-18 15:21:02.258 UTC [663701] 099_change_roles.pl LOG: INSERT @ 0/304DBF0:  - Transaction/COMMIT: 2024-01-18 15:21:02.258739+00 2024-01-18 15:21:02.258 UTC [663701] 099_change_roles.pl STATEMENT: INSERT INTO t VALUES (10, 'inserted on node1'); 2024-01-18 15:21:02.258 UTC [663701] 099_change_roles.pl LOG:  xlog flush request 0/304DBF0; write 0/0; flush 0/0 2024-01-18 15:21:02.258 UTC [663701] 099_change_roles.pl STATEMENT: INSERT INTO t VALUES (10, 'inserted on node1'); 2024-01-18 15:21:02.258 UTC [663671] node2 DEBUG:  write 0/304DBF0 flush 0/304DB78 apply 0/304DB78 reply_time 2024-01-18 15:21:02.2588+00 2024-01-18 15:21:02.258 UTC [663671] node2 DEBUG:  write 0/304DBF0 flush 0/304DBF0 apply 0/304DB78 reply_time 2024-01-18 15:21:02.258809+00 2024-01-18 15:21:02.258 UTC [663671] node2 DEBUG:  write 0/304DBF0 flush 0/304DBF0 apply 0/304DBF0 reply_time 2024-01-18 15:21:02.258864+00 2024-01-18 15:21:02.259 UTC [663563] DEBUG:  server process (PID 663701) exited with exit code 0 2024-01-18 15:21:02.260 UTC [663563] DEBUG:  forked new backend, pid=663704 socket=8 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl LOG: statement: INSERT INTO t VALUES (1000 * 1 + 608, 'background activity'); 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl LOG: INSERT @ 0/304DC40:  - Heap/INSERT: off: 12, flags: 0x00 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl STATEMENT: INSERT INTO t VALUES (1000 * 1 + 608, 'background activity'); 2024-01-18 15:21:02.261 UTC [663563] DEBUG:  postmaster received shutdown request signal 2024-01-18 15:21:02.261 UTC [663563] LOG:  received immediate shutdown request 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl LOG: INSERT @ 0/304DC68:  - Transaction/COMMIT: 2024-01-18 15:21:02.261828+00 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl STATEMENT: INSERT INTO t VALUES (1000 * 1 + 608, 'background activity'); 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl LOG:  xlog flush request 0/304DC68; write 0/0; flush 0/0 2024-01-18 15:21:02.261 UTC [663704] 099_change_roles.pl STATEMENT: INSERT INTO t VALUES (1000 * 1 + 608, 'background activity'); ... 2024-01-18 15:21:02.262 UTC [663563] LOG:  database system is shut down ... 2024-01-18 15:21:02.474 UTC [663810] LOG:  starting PostgreSQL 16.1 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, 64-bit ... 2024-01-18 15:21:02.478 UTC [663816] LOG:  REDO @ 0/304DBC8; LSN 0/304DBF0: prev 0/304DB78; xid 898; len 8 - Transaction/COMMIT: 2024-01-18 15:21:02.258739+00 2024-01-18 15:21:02.478 UTC [663816] LOG:  REDO @ 0/304DBF0; LSN 0/304DC40: prev 0/304DBC8; xid 899; len 3; blkref #0: rel 1663/5/16384, blk 1 - Heap/INSERT: off: 12, flags: 0x00 2024-01-18 15:21:02.478 UTC [663816] LOG:  REDO @ 0/304DC40; LSN 0/304DC68: prev 0/304DBF0; xid 899; len 8 - Transaction/COMMIT: 2024-01-18 15:21:02.261828+00 ... 2024-01-18 15:21:02.481 UTC [663819] LOG:  fetching timeline history file for timeline 20 from primary server 2024-01-18 15:21:02.481 UTC [663819] LOG:  started streaming WAL from primary at 0/3000000 on timeline 19 ... 2024-01-18 15:21:02.481 UTC [663819] DETAIL:  End of WAL reached on timeline 19 at 0/304DBF0. ... 2024-01-18 15:21:02.481 UTC [663816] LOG:  new timeline 20 forked off current database system timeline 19 before current recovery point 0/304DC68 In this case, node1 wrote to it's WAL record 0/304DC68, but sent to node2 only record 0/304DBF0, then node2, being promoted to primary, forked a next timeline from it, but when node1 was started as a standby, it first replayed 0/304DC68 from WAL, and then could not switch to the new timeline starting from the previous position. Reproduced on REL_12_STABLE .. master. Best regards, Alexander --------------2WjKRzPQvlP7FQoSlkG7Wwg1 Content-Type: application/x-perl; name="099_change_roles.pl" Content-Disposition: attachment; filename="099_change_roles.pl" Content-Transfer-Encoding: 7bit use strict; use warnings FATAL => 'all'; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; use Test::More; use IPC::Run; use threads; use threads::shared; sub bgactivity { my @args = @_; my ($n, $port, $db_name) = @args; $SIG{'KILL'} = sub { print("Thread killed.\n"); threads->exit(); }; my $try = 1; while (1) { my ($stdout, $stderr); my $cmd = [ 'psql', '-h', $ENV{'PGHOST'}, '-p', $port, '-d', $db_name, '-c', "INSERT INTO t VALUES (1000 * $n + $try, 'background activity');" ]; my $result = IPC::Run::run($cmd, '>', \$stdout, '2>', \$stderr); $try += 1; sleep(0.001); } } # Set up two replication nodes, which will switch roles. my $node1 = PostgreSQL::Test::Cluster->new("node1"); $node1->init(allows_streaming => 1); $node1->start; $node1->backup('initial_backup'); my $node2 = PostgreSQL::Test::Cluster->new('node2'); $node2->init_from_backup($node1, 'initial_backup', has_streaming => 1); $node2->start; $node1->psql('postgres', "ALTER SYSTEM SET synchronous_standby_names = 'node2'; SELECT pg_reload_conf()"); $node2->psql('postgres', "ALTER SYSTEM SET synchronous_standby_names = 'node1'; SELECT pg_reload_conf()"); $node1->psql('postgres', "CREATE TABLE t(id int, message text)"); my $numthreads = 2; my @threads; foreach my $ti (1 .. $numthreads) { push @threads, threads->create('bgactivity', $ti, $node1->port, 'postgres'); } for (my $i = 1; $i <= 20; $i++) { my ($primary, $standby) = ($node1, $node2); $primary->safe_psql('postgres', "INSERT INTO t VALUES ($i, 'inserted on node1');"); # change roles $primary->teardown_node; $standby->promote; $primary->enable_streaming($standby); $primary->start; ($primary, $standby) = ($node2, $node1); $primary->safe_psql('postgres', "INSERT INTO t VALUES ($i, 'inserted on node2');"); # change roles back $primary->teardown_node; $standby->promote; $primary->enable_streaming($standby); $primary->start; ok(1); } for my $thread (@threads) { $thread->kill('KILL')->detach; } done_testing(); --------------2WjKRzPQvlP7FQoSlkG7Wwg1--