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.96) (envelope-from ) id 1wXGW3-003A6Y-1F for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jun 2026 10:50:35 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wXGW2-00AnbX-1H for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jun 2026 10:50:34 +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.96) (envelope-from ) id 1wXGW2-00AnbP-00 for pgsql-hackers@lists.postgresql.org; Wed, 10 Jun 2026 10:50:34 +0000 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wXGW0-00000001zlu-0LUj for pgsql-hackers@lists.postgresql.org; Wed, 10 Jun 2026 10:50:32 +0000 Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-45f3cf907ceso3379139f8f.2 for ; Wed, 10 Jun 2026 03:50:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781088631; cv=none; d=google.com; s=arc-20240605; b=lYalcSLPJp4x8tKiGrdubMWwVb7gJJ1UxCOoxTl4Z8Bco+NNo0z00ymoIZW76Xxj5U fEYB8k89o75HBoVWvAxNFS8JUDYyA3Ur4DsFEaYev40LOjDsf+HMyltgoenjj25aMi1F n2qHHhsFzvhD0z5yDEsgF4++NR52az4KI+i9DtniLLj2CHrr62O/wAwY2Owf88ojekqM +xj9xQZEyvAIFX2Shs41FxWV3XYUJ/bd2EfWYL+7lZMSU2k8d5IoVZ7SefAliViolyfR uPmuuHrz5AdNr0cR2oXc9cUsYTR0L0asmrBF+MfDNC/bkJ3okVmSeLQWH4E93B6p1uQS M4Fw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=avKzJpNIttnvyoAIpWp/zMTdwZisjBwtDbKLizWOW04=; fh=//fSW77pnKgaNWJEKu62uIZb0puq/7IFWDkduIvFYoo=; b=OIGFpzEC1tROZs4xKB/luA0qZjaIWgWNrRmb6IvrqGhFugZQ70Kxg935K+Y1uuTglM +FOHNFWnkZPGCdMQFAeuJ42oebIc6A3vJIRur4sKGO2EuVkDqu1kUa3QVYNdy+Gacv5l dqmnBY56XPhCyGfuAejxjF8og94VcL8BjQzpaXhSPfJVgIaiWmMSNKMvZZkids3E/HXh 1u4Ig/4E0TEzN3n/jB8bxG+1vK6e7kxZOaA1sgFnmLxF9RC/3rPbhGG0iOcMUsk4yr3I kYdewH5Vl12Pw2N81+qY2HE/Ap7uenLyWZstmsvbcvseZ+MvKfnMeILsn+QfCqpiT7Ls j+3w==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781088631; x=1781693431; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=avKzJpNIttnvyoAIpWp/zMTdwZisjBwtDbKLizWOW04=; b=GJv5/HaY5S91oC2FLOwANamSdu7Imgx7YYlSNub3oPiXlR0+0l0FVdoWDglvokmRU/ SCwhucghpKvMqauVOwLB6Iqnd9qTzZmfwtskrYkXwU7Ouzfy4Tsxa6dbHJLWb05SB8VX guBxuI2IPWJvXzDgSNK8tv2jiMoIZLnvv964J1zTwE82oSpy3YwPPqQQz9HckK/B406h ubUVxRrfeAWb4kUHJcMZc633YCojNSP46bw0V6Ekt0QjmltXct9YhF1gEkrDIUpAr5Pf 5UIJdvT0Nz6aOpRoqYW2vdHiGM9NVmsyAdAlhz/u35antnNVFR30989GldvWfL+cMZEd bEWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781088631; x=1781693431; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=avKzJpNIttnvyoAIpWp/zMTdwZisjBwtDbKLizWOW04=; b=HnUcovUPcL3ZEanQpP4HI6nn/E9tFF11+KhtLKkF4N+zGFXhceWl7tCZSJO6TlOr9j ZNK3lu+bL/yyi+cSY3Fap1nt9coB2X3TiZOdZRB3hFbis/0VugMWEbRwpofR7BSdIu5H wezq8yhaZqnWZqpcXynqpcW2DZbmOhWyMvWN7p1zPpz8UiX7U8QpllRUsnx2CXjI1101 oXlmlILOrnUd3foihExEZcPl5YW/suPAQ9sLvl7QK2ps/4OVSr+evC+wOWPvCJMEUDse s499XOcAOuc4MGvb7ipnF55wPBTkwPsPPTnwtn1qn878hHmetatu2lndJdz6vCxGflqy T26Q== X-Forwarded-Encrypted: i=1; AFNElJ90X+ksQw1mN6BngEtldQxNVo7N+YH66kDJ0aOykuH8CFexofyiW9cZrV06jCV0URFzUlusI2em0Pxldkwq@lists.postgresql.org X-Gm-Message-State: AOJu0Yx/v4XR7OQV/tlcB32CKyJHzdaY1d7zbxGwjylwvT8ee7UJ1d/2 euquDOQwn401RjoRfpJ0nUsjtxiUiXGCfSrYqG1E/px3utHRAxu2Dzw6ZOXxxbfMwg5lUOfnZz5 fdIl12SXGSQt4+n5HpvTQO1wGGVQjT6UQPOnr X-Gm-Gg: Acq92OFOvmDkNMgEfjdKLA1ndg/m8EZ3AX48oxRTrMd06yfkxGCvsjMpemmLRS+h+ct PiflUO1YzDVVusNl0I8FS6SiJJWNVVL/w6YG1w4mmHrQSO7mkd5c6Tj3h8KeUtGPOY6hkmtl+P1 7/MmWTjbtMbNNjdldBDPDvivagxRy9+4TGwkW75n9wL8OKEYYtqRc6H0Wp7Ic6MfS1Qenl8bSXB K6xy8lp2x+bjExYheiUuvKau6GNow8kkjy/F0wFIcnQvxRprof6sKMpAhdUAPg0sP2FfzX4IlYL IiBboN5QI5jUR41uKKimAGOkplls64jEzvyFeuCAvpWh6qOcPalmw4kjqXA9lyaLtECJ6cllmd5 cBUgwXaANeGSBKrk/+PMrPFgZ3mcHVF8zWxuEFLHd13wxMGg+lZniI6WOcjqO570= X-Received: by 2002:a05:6000:178d:b0:460:51ef:f81f with SMTP id ffacd0b85a97d-46051eff8c0mr11759298f8f.6.1781088630362; Wed, 10 Jun 2026 03:50:30 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ashutosh Bapat Date: Wed, 10 Jun 2026 16:20:18 +0530 X-Gm-Features: AVVi8CdPqmHQxUEQQINijEDmRtwNRqyGH7VOWTwd_39aD84uh2DR3B5nG7nKFMU Message-ID: Subject: Re: GetBufferDescriptor() being called for local buffers from MarkBufferDirtyHint() To: Michael Paquier Cc: Andres Freund , PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Jun 10, 2026 at 9:10=E2=80=AFAM Michael Paquier wrote: > > On Sat, Jun 06, 2026 at 01:37:42PM +0530, Ashutosh Bapat wrote: > > 82467f627bd478569de04f4a3f1993098e80c812 added MarkBufferDirtyHint() > > which invokes GetBufferDescriptor() even for local buffers for which > > id < 0. Since GetBufferDescriptor() declares id as uint32, -1 is > > converted to a very large int32 value which is way larger than > > NBuffers. Thus GetBufferDescriptor() may be returning something from > > the BufferBlocks which probably has enough memory to accommodate that > > memory access. But it's a bogus BufferDesc nevertheless. We are not > > seeing any problem with this right now since MarkBufferDirtyHint() > > uses the BufferDesc only when it's a shared buffer. Right fix is to > > let that function handle local buffers first and then call > > GetBufferDescriptor() as in the attached patch. > > @@ -5831,8 +5831,6 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std) > { > BufferDesc *bufHdr; > > - bufHdr =3D GetBufferDescriptor(buffer - 1); > - > if (!BufferIsValid(buffer)) > elog(ERROR, "bad buffer ID: %d", buffer); > > @@ -5842,6 +5840,8 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std) > return; > } > > + bufHdr =3D GetBufferDescriptor(buffer - 1); > > Yep, that's clearly wrong. We are lucky that it does not blow up > today but that's a ticking bomb. Even with that in mind, the result > leads to a non-defined behavior. > > - return &(BufferDescriptors[id]).bufferdesc; > + BufferDesc *bdesc =3D &(BufferDescriptors[id]).bufferdesc; > + > + Assert(bdesc->buf_id =3D=3D id); > + > + return bdesc; > [...] > - BufferDesc *buf =3D GetBufferDescriptor(i); > + /* GetBufferDescriptor() expects buf_id to be set in the descrip= tor. */ > + BufferDesc *buf =3D &(BufferDescriptors[i]).bufferdesc; > > I am not convinced by these two. For the first one, the assertion is > a bound check in disguise, which could also use NBuffers as of an (id > < NBuffers). Just to clarify, it's stronger than just a bound check. BufferDesc::buf_id comment says /* * Buffer's index number (from 0). The field never changes after * initialization, so does not need locking. */ > With the inlining we care about the performance. This > also forces the second change in ShmemInit(), which makes even less > sense once we think about the first assertion. > The field is writable and can be accidentally written to. Imagine a bug *(wrong memory calculation) =3D changing buf_id without realising the change especially when is within 0 to NBuffers. There is no place where we check that the assumption is true. But we use buf_id in a few critical places. GetBufferDescriptor() is a good place for checking the assumption. I agree that there's a small risk that it will make accessing the buffer slower but only in Assert enabled builds which are anyway slower [1]. FWIW, I ran pgbench on my laptop with nproc =3D 16 with scale =3D 10. I didn't find any performance difference Without assertion $ for i in 1 2 3 4 5 6; do pgbench -d postgres -T 300 -c 4 -j 4 | grep tps;= done starting vacuum...end. tps =3D 1081.714940 (without initial connection time) starting vacuum...end. tps =3D 1026.242729 (without initial connection time) starting vacuum...end. tps =3D 1080.696554 (without initial connection time) starting vacuum...end. tps =3D 1092.211269 (without initial connection time) starting vacuum...end. tps =3D 1058.359337 (without initial connection time) starting vacuum...end. tps =3D 1087.718979 (without initial connection time) With Assertion $ for i in 1 2 3 4 5 6 ; do pgbench -d postgres -T 300 -c 4 -j 4 | grep tps; done starting vacuum...end. tps =3D 1065.345204 (without initial connection time) starting vacuum...end. tps =3D 1088.642703 (without initial connection time) starting vacuum...end. tps =3D 1077.954350 (without initial connection time) starting vacuum...end. tps =3D 1091.662205 (without initial connection time) starting vacuum...end. tps =3D 1029.412347 (without initial connection time) starting vacuum...end. tps =3D 1086.912667 (without initial connection time) Said that, I am fine, if we don't want to include the Assertion. I will keep it in my shared buffer resizing patches where I have found it useful. Maybe we will reconsider it with resizable shared buffers context. > Will fix the first issue on HEAD, that's wrong. Thanks for the > report. Thanks. [1] https://www.postgresql.org/message-id/CAExHW5tNMNQ5ennUM3QK%2BMQGw703M9= T6z-LvBKKAcgpJ3KW14Q%40mail.gmail.com -- Best Wishes, Ashutosh Bapat