Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jNtIk-0003ku-MD for pgsql-bugs@arkaria.postgresql.org; Mon, 13 Apr 2020 07:14:39 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jNtIj-0007cU-41 for pgsql-bugs@arkaria.postgresql.org; Mon, 13 Apr 2020 07:14:37 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jNtIg-0007b7-TN for pgsql-bugs@lists.postgresql.org; Mon, 13 Apr 2020 07:14:36 +0000 Received: from [64.147.123.24] (helo=wout1-smtp.messagingengine.com) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jNtId-0001x3-7o for pgsql-bugs@lists.postgresql.org; Mon, 13 Apr 2020 07:14:33 +0000 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id 806CF6CB; Mon, 13 Apr 2020 03:14:19 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Mon, 13 Apr 2020 03:14:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paquier.xyz; h= date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm1; bh=M6g9yCIJtWq1tqDNn8AgdouCMQw kIg2AHwGbzq1+ZQA=; b=eAzr8ZS5QLpKsSgL29nAZMQ/9t5v/Mz2o5Zxzvpvr9F n5OKdRosocr43LAlMXW/QfrLH9pfpJjQtE00utszpBpVgStQouvzh80W8i2vOIc4 UGChRpUkd1Jo+HlC41W6+NlMPD5Z1o3Zt+8T6PZQb0oaDWQK5uSZErsogEOt9UCM y3/mhKy2UHx1LBoyQGaUsdWAhW6Y4TyTnpHaQCFboxVoo0l4TEm0Gd9373BOJA8M ZaNRsCxbvQ94p9nMLs+3WtDnkUv1tOJ+PW6JhMIhsFCvPycODLThC3VjnUZm04NZ vPjWQVDzllk/bweTzoWaXThoSzRsQnEM3P0bDe76XEw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=M6g9yC IJtWq1tqDNn8AgdouCMQwkIg2AHwGbzq1+ZQA=; b=abwsh8XkswbS9nSB6oBuUr OyXJTe0ljTCrG66xKrnPBwgtpoumufS/wLBlU1oZ8At9S1k+KTnvfiUO7clqECfI dUO5vn4onbpoADCt5Z/nnRkerCHXzMCkct1vVLHM1a7KCdrO4r7BXsNcoujxiwZs 9wbULwdeF5sGT3fL5xY+sA+r7FV17MX2YEklUGtdJ4yvFtLzlUH0KYCoB1c5kcjC 4gD3dZ8QKEaXeSO8hXSX3amRvqz0tJw9PmPbvR944NTqbN+6m58I3XpwHoMX1mfJ 0xzHphFiuRXCQNuEdvFqdf5YRcOqmHeFHqDqvHoAi5gH37ctfzC6yxtkJ3WqXz7A == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrvdekgdduudelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdljedtmdenucfjughrpeffhf fvuffkfhggtggujgesghdtreertddtvdenucfhrhhomhepofhitghhrggvlhcurfgrqhhu ihgvrhcuoehmihgthhgrvghlsehprghquhhivghrrdighiiiqeenucfkphepudduuddrud dtvddrudektddrudekheenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgr ihhlfhhrohhmpehmihgthhgrvghlsehprghquhhivghrrdighiii X-ME-Proxy: Received: from paquier.xyz (ee0822lan1.rev.em-net.ne.jp [111.102.180.185]) by mail.messagingengine.com (Postfix) with ESMTPA id 313563060061; Mon, 13 Apr 2020 03:14:16 -0400 (EDT) Date: Mon, 13 Apr 2020 16:14:14 +0900 From: Michael Paquier To: Kyotaro Horiguchi Cc: jgdr@dalibo.com, masao.fujii@oss.nttdata.com, pgsql-bugs@lists.postgresql.org Subject: Re: [BUG] non archived WAL removed during production crash recovery Message-ID: <20200413071414.GF2169@paquier.xyz> References: <20200408022345.GC1606@paquier.xyz> <20200408135830.25a8e2ef@firost> <20200409184622.390f9b7f@firost> <20200410.111454.269125561493324950.horikyota.ntt@gmail.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="kadn00tgSopKmJ1H" Content-Disposition: inline In-Reply-To: <20200410.111454.269125561493324950.horikyota.ntt@gmail.com> X-Host-Lookup-Failed: Reverse DNS lookup failed for 64.147.123.24 (deferred) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --kadn00tgSopKmJ1H Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Apr 10, 2020 at 11:14:54AM +0900, Kyotaro Horiguchi wrote: > I have the same feeling with Michael. The test that archives are > created correctly seems to fit the file. It would be unintentionally > that the file is not exercising archiving so much. I have been finally looking at this thread and the latest patch set, sorry for the late reply. XLogCtl->XLogCacheBlck =3D XLOGbuffers - 1; - XLogCtl->SharedRecoveryInProgress =3D true; XLogCtl->SharedHotStandbyActive =3D false; XLogCtl->SharedPromoteIsTriggered =3D false; XLogCtl->WalWriterSleeping =3D false; [...] + switch (ControlFile->state) + { + case DB_SHUTDOWNED: + case DB_SHUTDOWNED_IN_RECOVERY: + XLogCtl->SharedRecoveryState =3D ARCHIVE_RECOVERING; + break; + default: + XLogCtl->SharedRecoveryState =3D CRASH_RECOVERING; + } It seems to me that the initial value of SharedRecoveryState should be CRASH_RECOVERING all the time no? StartupXLOG() is a code path taken even if starting cleanly, and the flag would be reset correctly at the end to NOT_IN_RECOVERY. +typedef enum RecoveryState +{ + NOT_IN_RECOVERY =3D 0, /* currently in production */ + CRASH_RECOVERING, /* recovering from a crash */ + ARCHIVE_RECOVERING /* recovering archives as requested */ +} RecoveryState; I also have some issues with the name of those variables, here is an idea for the three states: - RECOVERY_STATE_CRASH - RECOVERT_STATE_ARCHIVE - RECOVERY_STATE_NONE I would recommend to use the same suffix for those variables to ease grepping. /* - * Local copy of SharedRecoveryInProgress variable. True actually means "n= ot - * known, need to check the shared state". + * This is false when SharedRecoveryState is not ARCHIVE_RECOVERING. + * True actually means "not known, need to check the shared state". */ A double negation sounds wrong to me. And actually this variable is false when the shared state is set to NOT_IN_RECOVERY, and true when the state is either CRASH_RECOVERING or ARCHIVE_RECOVERING because it means that recovery is running, be it archive recovery or crash recovery, so the comment is wrong. + /* The file is always deletable if archive_mode is "off". */ + if ( ! XLogArchivingActive() ) + return true; [...] + if ( recoveryState =3D=3D ARCHIVE_RECOVERING && !XLogArchivingAlways() ) return true; Incorrect indentation. UpdateControlFile(); + + SpinLockAcquire(&XLogCtl->info_lck); + XLogCtl->SharedRecoveryState =3D ARCHIVE_RECOVERING; + SpinLockRelease(&XLogCtl->info_lck); + LWLockRelease(ControlFileLock); Here, the shared flag is updated while holding ControlFileLock to ensure a consistent state of things within shared memory, so it would be nice to add a comment about that. +RecoveryState +GetRecoveryState(void) +{ + volatile XLogCtlData *xlogctl =3D XLogCtl; + + return xlogctl->SharedRecoveryState; +} Er, you need to acquire info_lck to look at the state here, no? /* - * The file is always deletable if archive_mode is "off". On standbys - * archiving is disabled if archive_mode is "on", and enabled with - * "always". On a primary, archiving is enabled if archive_mode is "on" - * or "always". + * On standbys, the file is deletable if archive_mode is not + * "always". */ It would be good to mention that while in crash recovery, files are not considered as deletable. I agree that having a separate .pl file for the tests of this thread is just cleaner. Here are more comments about these. +# temporary fail archive_command for futur tests +$node->safe_psql('postgres', q{ + ALTER SYSTEM SET archive_command TO 'false'; + SELECT pg_reload_conf(); +}); That's likely portable on Windows even if you skip the tests there, and I am not sure that it is a good idea to rely on it being in PATH. Depending on the system, the path of the command is also likely going to be different. As here the goal is to prevent the archiver to do its work, why not relying on the configuration where archive_mode is set but archive_command is not? This would cause the archiver to be a no-op process, and .ready files will remain around. You could then replace the lookup of pg_stat_archiver with poll_query_until() and a query that makes use of pg_stat_file() to make sure that the .ready exists when needed. + ok( -f "$node_data/pg_wal/archive_status/000000010000000000000001.ready", + "WAL still ready to archive in archive_status"); It would be good to mention in the description the check applies to a primary. +# test recovery without archive_mode=3Dalways does not keep .ready WALs +$standby1 =3D get_new_node('standby'); +$standby1->init_from_backup($node, 'backup', has_restoring =3D> 1); +$standby1_data =3D $standby1->data_dir; +$standby1->start; +$standby1->safe_psql('postgres', q{CHECKPOINT}); For readability archive_mode =3D on should be added to the configuration file? Okay, this is inherited from the primary, still that would avoid any issues with this code is refactored in some way. "WAL waiting to be archived in backup removed with archive_mode=3Don on standby" ); = =20 That should be "WAL segment" or "WAL file", but not WAL. Regarding the tests on a standby, it seems to me that the following is necessary: 1) Test that with archive_mode =3D on, segments are not marked with =2Eready. 2) Test that with archive_mode =3D always, segments are marked with =2Eready during archive recovery. 3) Test that with archive_mode =3D always, segments are not removed during crash recovery. I can see tests for 1) and 2), but not 3). Could you add a stop('immediate')+start() for $standby2 at the end of 020_archive_status.pl and check that the .ready file is still there after crash recovery? The end of the tests actually relies on the fact that archive_command is set to "false" when the cold backup is taken, before resetting it. I think that it would be cleaner to enforce the configuration you want to test before starting each standby. It becomes easier to understand the flow of the test for the reader. -- Michael --kadn00tgSopKmJ1H Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAl6UEUYACgkQnvQgOdby QH0EeA/+Ov9lWAEBe1dHhG2r7kFI8V9NieFLNtnQa0JzyMYqBI3V26jNOU/M/FJe oHzwyB3i1ta7w6e4k7yYRUvi7ZDoTevn+OoOe28fC69ap5yb4IMOcf0zrpqOflwH 2AKLCIHPUbdkcTtIDz08S2rbNjM4CE2hcon6ZqfMSI72eq967AyqoDM0Y7gb4zF7 uhiWGbKznZuuv0zc92qMQJ579u8xB6W/jZiOI/WCRBP54FcDzIgrhOviTWLFMYFW D11NxfGg7ae4WbVBd6seEqXBqZJl+4DsumPOFW4P1hPBmAx2YcB6cNsQC9hL6lMn v++gIiexBUVahXrujHo85GSm/nZu1MoDK+ypGrJJFIpfarCbrG8S5lsqh1QRAsgd BLEIWR9xmkNfvM6dOG3Dd5Kg6CP5pasCQ5NP4cn6EC/i51aB+BH+E0P1anyR2C06 MfuctpHAyVunrTDzg8yywTubkPxiwAHQ+51EmZSE/qWyBqJxQfSgw75aoiTlIavC +fZwEPa7k4aoRnPx9fSSvszfS/A1jcQ4eamK+hoph5ade/wA16RSGkDbSOD+GHbx 2RpkoqwYVxPEXhfD1c+MeNTqYFvOZnyW4rLFaIOPDf8HF77nb3FcafsNiHQkf99o TpegJFTXO0i4so+33ma/3sfoIwZPqizhscV79R7C+Pnl+v6Oiw0= =f895 -----END PGP SIGNATURE----- --kadn00tgSopKmJ1H--