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 1mmoNc-0002Gg-57 for pgsql-bugs@arkaria.postgresql.org; Tue, 16 Nov 2021 02:39:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mmoNb-0005Jx-4U for pgsql-bugs@arkaria.postgresql.org; Tue, 16 Nov 2021 02:39:27 +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 1mmoNa-0005Jn-3S for pgsql-bugs@lists.postgresql.org; Tue, 16 Nov 2021 02:39:26 +0000 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mmoNX-0002z9-3O for pgsql-bugs@lists.postgresql.org; Tue, 16 Nov 2021 02:39:25 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id E8C6D3201C29; Mon, 15 Nov 2021 21:39:20 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Mon, 15 Nov 2021 21:39:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anarazel.de; h= date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm3; bh=oESs8WRZqr+u0ihXqA4kQpHmC79 ai497o8rbcUMyIuo=; b=GuD0o0nCWj6sj/03lSfehk85D3tCG+ebXdpKYsapD+7 h6IIsCrxN5rJ+eE7iJTgV7m9mSckGU7KH5otjzN2FyUuDKbRPcaj47yF1bWZzT/c K0IjTK9MqKQy0tDmm8HIHo9XmvFEI6AiAUNcnKxNHtRkNtgKgn3Idqb/yGT5Tsbp EZA3sCQOpeWm52k15KfGjmEeH44o94geo5wx2J7uCB8Zim/amgYL5HYZGPkfzbqA RUFaaMT/HoqvVkT5UA3L4J2zzBIw+HbYYie9/eyRfgX75pmA6rG9BbB9sC725Xhc vmJNBABeyOoU3N4P0RO0WBRH7tP0Q3GcXn6xA5Y2kGQ== 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=fm1; bh=oESs8W RZqr+u0ihXqA4kQpHmC79ai497o8rbcUMyIuo=; b=N+6HkXC5Sp8aw4LMqiiPaJ Los0DIeZxf5tSAczyPSZC8Rgj3EhkVng5PHwxKyrdF69uAeLquTRc35sDR/FcOyG CdUdeW6OQACQ1D3wNoCzwksAuKGbXWMK+t2yzHTHKDKkAcLf3AjQ2jyCmTy/Z3GK 7Hq4vj+t4V5BcQO82QEpu7oKnFsQ0WpVzBaWHbp2hRU72DmgWP+6mtQOrm+RYWn3 xVsIXAOS369jUVqQgkrebe0jsD/8VN+LKdM5p7xAKPSpjSGsAheGUpbgJCyBcdQn F6UuB6IK2Ny7Wyk7Dl7X46pZILpzMUVA4sPT8VUXOTFjGITdqmuBY+uNSZUX8aww == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrfedugdegiecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvuffkfhggtggujgesthdtredttddtvdenucfhrhhomheptehnughrvghs ucfhrhgvuhhnugcuoegrnhgurhgvshesrghnrghrrgiivghlrdguvgeqnecuggftrfgrth htvghrnhepudekhfekleeugeevteehleffffejgeelueduleeffeeutdelffeujeffhfeu ffdunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprg hnughrvghssegrnhgrrhgriigvlhdruggv X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 15 Nov 2021 21:39:20 -0500 (EST) Date: Mon, 15 Nov 2021 18:39:18 -0800 From: Andres Freund To: Peter Geoghegan Cc: Dmitry Dolgov <9erthalion6@gmail.com>, Alexander Lakhin , Matthias van de Meent , PostgreSQL mailing lists Subject: Re: BUG #17255: Server crashes in index_delete_sort_cmp() due to race condition with vacuum Message-ID: <20211116023918.5g6d6izevronx76m@alap3.anarazel.de> References: <20211030213948.3i3f7cieqxzhd7kq@alap3.anarazel.de> <20211031192051.e3r2uxft3bulymrr@localhost> <08c2445c-c3c9-ba45-18d3-6399707d8306@gmail.com> <20211108172852.pvsarxoxi54uatch@localhost> <20211109150216.fgfybn35mwnkeef3@localhost> <20211111030821.2xxl75qfkynaga4j@alap3.anarazel.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20211111030821.2xxl75qfkynaga4j@alap3.anarazel.de> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, On 2021-11-10 19:08:21 -0800, Andres Freund wrote: > On 2021-11-09 19:07:02 -0800, Peter Geoghegan wrote: > > @@ -700,11 +720,18 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate) > > } > > > > /* > > - * Remember the last DEAD tuple seen. We will advance past > > - * RECENTLY_DEAD tuples just in case there's a DEAD one after them; > > - * but we can't advance past anything else. We have to make sure that > > - * we don't miss any DEAD tuples, since DEAD tuples that still have > > - * tuple storage after pruning will confuse VACUUM. > > + * Remember the last DEAD tuple seen from this HOT chain. > > + * > > + * We expect to sometimes find a RECENTLY_DEAD tuple after a DEAD > > + * tuple. When this happens, the RECENTLY_DEAD tuple will be treated > > + * as if it was DEAD all along. Manage that now. > > I now actually wonder why this is correct. There's another comment about it: > > > We also prune any RECENTLY_DEAD tuples preceding a DEAD tuple. > > * This is OK because a RECENTLY_DEAD tuple preceding a DEAD tuple is really > > But that doesn't justify very much. > > What prevents the scenario that some other backend e.g. has a snapshot with > xmin=xmax=RECENTLY_DEAD-row. If the RECENTLY_DEAD row has an xid that is later > than the DEAD row, this afaict would make it perfectly legal to prune the DEAD > row, but *not* the RECENTLY_DEAD one. I think the code is actually correct if awfully commented. I.e. the above scenario cannot happen in a harmful situation. The relevant piece is that the set of "valid" snapshots is limited (for a specific cluster history). A row can only be RECENTLY_DEAD if the deleting / updating transaction committed. An intermediary RECENTLY_DEAD row followed by a DEAD row would only be visible to a snapshot that either had 1) row.xmax >= Snapshot.xmax 2) row.xmax in Snapshot.xip. There cannot be a snapshot that sees the RECENTLY_DEAD row while also seeing the subsequent row as DEAD, because the existence of one of the two conditions would have held back the xid horizon: 1) is not possible, because Snapshot.xmin is <= Snapshot.xmax, and Snapshot.xmin >= MyProc->xmin. The subsequent row could not be DEAD. 2) is not possible, because .xip only contains xids >= Snapshot.xmin. IOW, there *can* be a snapshot with xmin=xmax=RECENTLY_DEAD-row, but it'd not see the RECENTLY_DEAD row anyway. Greetings, Andres Freund