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 1oefSm-0001YP-Te for pgsql-committers@arkaria.postgresql.org; Sat, 01 Oct 2022 16:35:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oefSl-0006h7-OH for pgsql-committers@arkaria.postgresql.org; Sat, 01 Oct 2022 16:35:39 +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 1oefSl-0006gy-DY for pgsql-committers@lists.postgresql.org; Sat, 01 Oct 2022 16:35:39 +0000 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1oefSh-0000eV-KB for pgsql-committers@lists.postgresql.org; Sat, 01 Oct 2022 16:35:38 +0000 Received: by mail-pl1-x635.google.com with SMTP id jo24so5841450plb.13 for ; Sat, 01 Oct 2022 09:35:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=j-davis-com.20210112.gappssmtp.com; s=20210112; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:from:to:cc:subject :date; bh=eWo/rRsqT2S31fNSEmxR+uDWB4WIBnkDCF0/g56p+/A=; b=WzoIXMDiFPzWVp3UYfA2hDJT24I3jXY1PStWThD41pHtiWzmBjLjkxE69AjMWfOif4 srebz566WXMdBWGnip6+G8gYE9xXI4dF0csmYubKUymrdbJ86zb+LJaooT2yJjgcnnCo UWdImtLwCBC+1qmj0fXlQ0gJ4AI+4OdwXR7AXUNHI0da+wrkOmEADLBXJOI4rLm0XK2m yk9frGGvPcFXcHyDg69Aw05lxi3trNo5f0IlVQrRfFr08rCHY11CmV4MSc4cc0AaCmDP CrgURNN/+KF9Jf/7Exkt2PvJdh7+mjG0mGSmxpQubrvjBNviOT8VYOT+jLNweFQugvJV OweA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:x-gm-message-state :from:to:cc:subject:date; bh=eWo/rRsqT2S31fNSEmxR+uDWB4WIBnkDCF0/g56p+/A=; b=mMtjd+JPBJDqeFaLPB5gQezoXeWIazxnqjPq0Xhm/21WfrVb15veFxmPExatiHCY4y 131dT0IAbE6PjJ/mzsNpYyHpWnXt6tInI+V4ESTReGN4dm9jVfHIMegfuikvG3ZfwZ6l 5ilg3SKqfByhYjGaBK3AX5ltvouVuLoZXrpDErGcT4ZH/71VPYU38H3Qzt4EEu/D3Tqt RQkBD2aibizeSxcipt+LhMJIyd+E6iyxn7c177xYURH5128j4d1vnbYI3VzsgVVPE48w uGRHQ76xBhJK/g9SQVTwnjiyyLw4pDAio3xYrZ9irDhHS3tQsw6ZIPjd3ARj+VDiVHQ0 iZFQ== X-Gm-Message-State: ACrzQf0wi85ECxnGAiUvGlAZmLomteJHTMtfQlQSGtezqzRTkhYrRIlc qxq/CbNZ/KT2hOg2deZy2uWSJw== X-Google-Smtp-Source: AMsMyM7kBkUV0URxEMBVVfJ7LumWLo+bwTuyWQUvMl2tvcNujWIBydKXFqccnTecYGHAEOzWRrM5yg== X-Received: by 2002:a17:90b:3ec9:b0:203:246e:4370 with SMTP id rm9-20020a17090b3ec900b00203246e4370mr3960759pjb.221.1664642134015; Sat, 01 Oct 2022 09:35:34 -0700 (PDT) Received: from [172.32.0.233] ([12.161.174.90]) by smtp.gmail.com with ESMTPSA id x15-20020a170902ec8f00b001780e4e1a0fsm4173950plg.125.2022.10.01.09.35.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Oct 2022 09:35:32 -0700 (PDT) Message-ID: Subject: Re: pgsql: Avoid improbable PANIC during heap_update. From: Jeff Davis To: Peter Geoghegan , Tom Lane Cc: Jaime Casanova , pgsql-committers@lists.postgresql.org Date: Sat, 01 Oct 2022 09:35:31 -0700 In-Reply-To: References: <692791.1664573331@sss.pgh.pa.us> <741997.1664574971@sss.pgh.pa.us> <841352.1664581964@sss.pgh.pa.us> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.1-0ubuntu1 MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri, 2022-09-30 at 21:23 -0700, Peter Geoghegan wrote: > 2490=C2=A0=C2=A0=C2=A0=C2=A0 page =3D BufferGetPage(buffer); > 2491 > 2492=C2=A0=C2=A0=C2=A0=C2=A0 /* > 2493=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Before locking the buffer, pin the v= isibility map page if > it appears to > 2494=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * be necessary.=C2=A0 Since we haven't= got the lock yet, someone > else might be > 2495=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * in the middle of changing this, so w= e'll need to recheck > after we have > 2496=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * the lock. > 2497=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 */ > 2498=C2=A0=C2=A0=C2=A0=C2=A0 if (PageIsAllVisible(page)) > 2499=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 visibilitymap_pin(re= lation, block, &vmbuffer); >=20 > So we're calling visibilitymap_pin() having just acquired a buffer > pin > on a heap page buffer for the first time, and without acquiring a > buffer lock on the same heap page (we don't hold one now, and we've > never held one at some earlier point). >=20 > Without Jeff's bugfix, nothing stops heap_delete() from getting a pin > on a heap page that happens to have already been cleanup locked by > another session running VACUUM. The same session could then > (correctly) observe that the page does not have PD_ALL_VISIBLE set -- > not yet.=C2=A0 With you so far; I had considered this code path and was still unable to repro. > VACUUM might then set PD_ALL_VISIBLE, without having to > acquire any kind of interlock that heap_delete() will reliably > notice. > After all, VACUUM had a cleanup lock before the other session's call > to heap_delete() even began -- so the responsibility has to lie with > heap_delete(). Directly after the code you reference above, there is (in 5f9dda4c06, right before my patch): 2501 LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); 2502=20 2503 /* =20 2504 * If we didn't pin the visibility map page and the page has become all =20 2505 * visible while we were busy locking the buffer, we'll have to unlock and =20 2506 * re-lock, to avoid holding the buffer lock across an I/O.=20 That's a bit =20 2507 * unfortunate, but hopefully shouldn't happen often. =20 2508 */ 2509 if (vmbuffer =3D=3D InvalidBuffer && PageIsAllVisible(page)) 2510 { 2511 LockBuffer(buffer, BUFFER_LOCK_UNLOCK); 2512 visibilitymap_pin(relation, block, &vmbuffer); 2513 LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); 2514 } Doesn't that deal with the case you brought up directly? heap_delete() can't get the exclusive lock until VACUUM releases its cleanup lock, at which point all-visible will be set. Then heap_delete() should notice in line 2509 and then pin the VM buffer. Right? And I don't think a similar issue exists when the locks are briefly released on lines 2563 or 2606. The pin is held until after the VM bit is cleared (aside from an error path and an early return): 2489 buffer =3D ReadBuffer(relation, block); ... 2717 if (PageIsAllVisible(page)) 2718 { 2719 all_visible_cleared =3D true; 2720 PageClearAllVisible(page); ... 2835 ReleaseBuffer(buffer); If VACCUM hasn't acquired the cleanup lock before 2489, it can't get one until heap_delete() is done looking at the all-visible bit anyway. So I don't see how my patch would have fixed it even if that was the problem. Of course, I must be wrong somewhere, because the bug seems to exist. --=20 Jeff Davis PostgreSQL Contributor Team - AWS