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 1qsp5I-009dcj-JP for pgsql-hackers@arkaria.postgresql.org; Tue, 17 Oct 2023 18:46:28 +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 1qsp5G-00DEWp-3C for pgsql-hackers@arkaria.postgresql.org; Tue, 17 Oct 2023 18:46:26 +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 1qsp5F-00DEWg-Pf for pgsql-hackers@lists.postgresql.org; Tue, 17 Oct 2023 18:46:26 +0000 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qsp59-000xjo-Fj for pgsql-hackers@lists.postgresql.org; Tue, 17 Oct 2023 18:46:25 +0000 Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2bfed7c4e6dso76138951fa.1 for ; Tue, 17 Oct 2023 11:46:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697568378; x=1698173178; 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=DIwBH6ZXy3zXSYIRZdnjCIG2E7NRFg5rmAm5I3Dzzb0=; b=j6MXSnVcj2kk1VLo1OgANJH99A8l8XC29u6CaiAluwoNSJsAZd7GxPzXGkbj6D94mX iLR5w2cQC4zIRRcmtdeHyozEAfNTOA2yX4yzS8RP2xcoGEG1MCwm+lw/Fx7BXrT4A++g emB/LkcegGsH97wVbrh+WvFDV7irluEfI/0cuu36gsEBqQkm5NWKMlnZ7FDBrOfyMpHz COXIVX0Y+d2AobaQ6Xu5uz9cXVi1loXzEQWPFK8v6Ci72E4AhctWozYlYZgazs5hOPfZ 3QrA88Eyg0FAqr8/wFCCQkTX9TuFlTetMQ1XpiSmIkLhgrsTdgK2tD8HDdsxn6tGBYEO 4cfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697568378; x=1698173178; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DIwBH6ZXy3zXSYIRZdnjCIG2E7NRFg5rmAm5I3Dzzb0=; b=nM8mMFpKXIgmwvb8ZJ0ukigJ710H4nJOxiBpJ7uzhQ4jQePkQcEriOh9zXZdy0Oonz 7BJbAGVBK4pDG32HkpeS5RFNvCGjTbIIInlWDFg9ZsELR/76X8ZLeavZWMshbm8SiioI GBB34a5Vosxd/4hFBHJjaJ6LiVNtFhEpSvG4RqjjQnhavNkbTszd1+Yt1QXDJj+kAeV5 r9vmqg90oyFz05/1z8BxSZ7IuXxP2S6w5ci40hXu5el5M2c8j+QOH0CD4cPSs+kS+nQE bqNK8iCSNssSjEyaUrVLrdw88NklI5vAHU6iWbtewcrIFoVZr4VghgIwL5+E6RXxGJ5B C2Aw== X-Gm-Message-State: AOJu0Yz9qJCK5RE7MMZxrYECpQJidSfpSuf3NvxmyHemUmbvqoXVioXX WnC7RntIJlxc0nC90NtCba7zdbmYnrU2wIbPpFM= X-Google-Smtp-Source: AGHT+IGd1Vn086De7XwJG1s53NXout690wFwyK/zHU7JmQk7I/LcI7Aut3grJpo8OyynVmBJj2wTlnTFiITMzrZAjF0= X-Received: by 2002:a05:651c:2da:b0:2b9:412a:111d with SMTP id f26-20020a05651c02da00b002b9412a111dmr2127408ljo.42.1697568377393; Tue, 17 Oct 2023 11:46:17 -0700 (PDT) MIME-Version: 1.0 References: <82dad3ca-035c-c5f3-d230-ff7d11b6e573@iki.fi> In-Reply-To: <82dad3ca-035c-c5f3-d230-ff7d11b6e573@iki.fi> From: Bharath Rupireddy Date: Wed, 18 Oct 2023 00:16:05 +0530 Message-ID: Subject: Re: Track Oldest Initialized WAL Buffer Page To: Heikki Linnakangas Cc: PostgreSQL Hackers , Nathan Bossart 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 Mon, Jul 3, 2023 at 6:57=E2=80=AFPM Heikki Linnakangas = wrote: > Thanks a lot for responding. Sorry for being late. > On 07/02/2023 16:00, Bharath Rupireddy wrote: > > Hi, > > > > While working on [1], I was looking for a quick way to tell if a WAL > > record is present in the WAL buffers array without scanning but I > > couldn't find one. > > /* The end-ptr of the page that contains the record */ > expectedEndPtr +=3D XLOG_BLCKSZ - recptr % XLOG_BLCKSZ; > > /* get the buffer where the record is, if it's in WAL buffers at all */ > idx =3D XLogRecPtrToBufIdx(recptr); > > /* prevent the WAL buffer from being evicted while we look at it */ > LWLockAcquire(WALBufMappingLock, LW_SHARED); > > /* Check if the page we're interested in is in the buffer */ > found =3D XLogCtl->xlblocks[idx] =3D=3D expectedEndPtr; > > LWLockRelease(WALBufMappingLock, LW_SHARED); This is exactly what I'm doing in the 0001 patch here https://www.postgresql.org/message-id/CALj2ACU3ZYzjOv4vZTR+LFk5PL4ndUnbLS6E= 1vG2dhDBjQGy2A@mail.gmail.com. My bad! I should have mentioned the requirement properly - I want to avoid taking WALBufMappingLock to peek into wal_buffers to determine if the WAL buffer page containing the required WAL record exists. > You actually hint at the above solution here, so I'm confused. If you're > OK with slightly stale results, you can skip the WALBufferMappingLock > above too, and perform an atomic read of xlblocks[idx] instead. I get that and I see GetXLogBuffer first reading xlblocks without lock and then to confirm it anyways takes the lock again in AdvanceXLInsertBuffer. * However, we don't hold a lock while we read the value. If someone ha= s * just initialized the page, it's possible that we get a "torn read" o= f * the XLogRecPtr if 64-bit fetches are not atomic on this platform. In * that case we will see a bogus value. That's ok, we'll grab the mappi= ng * lock (in AdvanceXLInsertBuffer) and retry if we see anything else th= an * the page we're looking for. But it means that when we do this unlock= ed * read, we might see a value that appears to be ahead of the page we'r= e * looking for. Don't PANIC on that, until we've verified the value whi= le * holding the lock. */ The the 0001 patch at https://www.postgresql.org/message-id/CALj2ACU3ZYzjOv4vZTR+LFk5PL4ndUnbLS6E= 1vG2dhDBjQGy2A@mail.gmail.com reads the WAL buffer page with WALBufMappingLock. So, the patch can avoid WALBufMappingLock and do something like [1]: [1] { idx =3D XLogRecPtrToBufIdx(ptr); expectedEndPtr =3D ptr; expectedEndPtr +=3D XLOG_BLCKSZ - ptr % XLOG_BLCKSZ; /* * Do a stale read of xlblocks without WALBufMappingLock. All the calle= rs * of this function are expected to read WAL that's already flushed to = disk * from WAL buffers. If this stale read says the requested WAL buffer p= age * doesn't exist, it means that the WAL buffer page either is being or = has * already been replaced for reuse. If this stale read says the request= ed * WAL buffer page exists, we then take WALBufMappingLock and re-read t= he * xlblocks to ensure the WAL buffer page really exists and nobody is * replacing it meanwhile. */ endptr =3D XLogCtl->xlblocks[idx]; /* Requested WAL isn't available in WAL buffers. */ if (expectedEndPtr !=3D endptr) break; /* * Requested WAL is available in WAL buffers, so recheck the existence * under the WALBufMappingLock and read if the page still exists, other= wise * return. */ LWLockAcquire(WALBufMappingLock, LW_SHARED); endptr =3D XLogCtl->xlblocks[idx]; /* Requested WAL isn't available in WAL buffers. */ if (expectedEndPtr !=3D endptr) break; /* * We found the WAL buffer page containing the given XLogRecPtr. Get starting * address of the page and a pointer to the right location given * XLogRecPtr in that page. */ page =3D XLogCtl->pages + idx * (Size) XLOG_BLCKSZ; data =3D page + ptr % XLOG_BLCKSZ; return data; } -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com