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 1rsnmu-009LhZ-Ns for pgsql-hackers@arkaria.postgresql.org; Fri, 05 Apr 2024 17:55:41 +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 1rsnmt-003l2d-Lm for pgsql-hackers@arkaria.postgresql.org; Fri, 05 Apr 2024 17:55:39 +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 1rsnms-003l1r-Mk for pgsql-hackers@lists.postgresql.org; Fri, 05 Apr 2024 17:55:39 +0000 Received: from fhigh5-smtp.messagingengine.com ([103.168.172.156]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rsnmp-000mnw-Qx for pgsql-hackers@lists.postgresql.org; Fri, 05 Apr 2024 17:55:37 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfhigh.nyi.internal (Postfix) with ESMTP id 7A28211400BC; Fri, 5 Apr 2024 13:55:34 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Fri, 05 Apr 2024 13:55:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1712339734; x= 1712426134; bh=rCULnmAPBdbnw6rsJsvzsr98sDd2ZT+86XDxlGrrvAw=; b=x RdplHN6TkVEC35/rO2fkcPupjwvy7CoXp1mLne6B8cfnZ+tDnYEiYuhr4L/is4dQ 8CopCeNaxOzr9y3GSnCZAtjWL0jv4Aw4zXrdVdjkaCJNGIkwJtLVPQM0w+J9NUHQ VCXjLoQkpQhJVYxZLQFNthaCQ0ZW5DylciuupCT6lchJSm85RW2PkIc2VuUC8j/e vAm3dLYXOb3kBKK+la8SB6Lni2TO258T3Y1LzzlBtP+jypeKGlxYcJVit9j8/AAv vtgN7NEXqmosaxyWVdfQUOATpNfp+7DFn8CH+rgzvJSJTli4JN4C+/vISYjgA9CW 3EEvS+O4NsxGpSMABGkXg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrudegtddguddulecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvvefukfggtggugfgjsehmkeerredttdejnecuhfhrohhmpeetlhhv rghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgesrghlvhhhrdhnohdqihhprdhorh hgqeenucggtffrrghtthgvrhhnpeduleekkefgtddttedtkefguddvieffleetgeejiefh teehkeevfeettdduvdfhueenucffohhmrghinhepvghnthgvrhhprhhishgvuggsrdgtoh hmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghl vhhhvghrrhgvsegrlhhvhhdrnhhoqdhiphdrohhrgh X-ME-Proxy: Feedback-ID: ia2694551:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 5 Apr 2024 13:55:33 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alvh.no-ip.org; s=schmee; t=1712339732; bh=YmqFhRS8335U2BYzkSL4ERGtRrK7F5GX0mmRAioTtVk=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=aFXiF/89k+jC22BFzGG/P9qmH53HqgW+HXmhzffOix1ksR+5aSw/1Ohe1K6VaJkij qbU6ca0gUFUv1FmqeqVVWPoFQoidy3h2KnPH6vsUtgDECa2QIWzcpoXVSZKx88o3z6 PAEWeGX5/DLUl32fkaaunG0v8RYYSb2OhE2X+vpQQWZzN7zSHKMk3S6kolcD8lqfc5 ptUsnwNcvtc4c9885LR6bH1xEzWcVqRplIrPRbBJrxtR/vOfN7iBc88kRFq1BxOhGU lRlGM5S0Lsw7fcuutb5aJ6NGehravTxVYYWPbgCxAnNhzT6LHFAJPHFOoA7OXm/6+W fVvWVnUwNzg6Q== Received: by schmee.alvh.no-ip.org (Postfix, from userid 1000) id 4B96346F; Fri, 5 Apr 2024 19:55:32 +0200 (CEST) Date: Fri, 5 Apr 2024 19:55:32 +0200 From: Alvaro Herrera To: Bharath Rupireddy Cc: Jeff Davis , Tom Lane , Andres Freund , pgsql-hackers@lists.postgresql.org, Jaime Casanova Subject: Re: LogwrtResult contended spinlock Message-ID: <202404051755.uir4j6ulp2jx@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="faz4ffo26psjwnc7" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <202404051154.am63tvpedo5p@alvherre.pgsql> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --faz4ffo26psjwnc7 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Pushed 0001. Here's the patch that adds the Copy position one more time, with the monotonic_advance function returning the value. -- Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/ --faz4ffo26psjwnc7 Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v17-0002-Add-logCopyResult.patch" From 3f5c860576245b92701e7bfc517947c418c68510 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 5 Apr 2024 13:52:44 +0200 Subject: [PATCH v17] Add logCopyResult Updated using monotonic increment --- src/backend/access/transam/xlog.c | 32 ++++++++++++++++++++++++++- src/include/port/atomics.h | 36 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index b4499cda7b..a40c1fb79e 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -469,6 +469,7 @@ typedef struct XLogCtlData XLogRecPtr lastSegSwitchLSN; /* These are accessed using atomics -- info_lck not needed */ + pg_atomic_uint64 logCopyResult; /* last byte + 1 copied to WAL buffers */ pg_atomic_uint64 logWriteResult; /* last byte + 1 written out */ pg_atomic_uint64 logFlushResult; /* last byte + 1 flushed */ @@ -1499,6 +1500,7 @@ static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto) { uint64 bytepos; + XLogRecPtr copyptr; XLogRecPtr reservedUpto; XLogRecPtr finishedUpto; XLogCtlInsert *Insert = &XLogCtl->Insert; @@ -1507,6 +1509,11 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto) if (MyProc == NULL) elog(PANIC, "cannot wait without a PGPROC structure"); + /* check if there's any work to do */ + copyptr = pg_atomic_read_u64(&XLogCtl->logCopyResult); + if (upto <= copyptr) + return copyptr; + /* Read the current insert position */ SpinLockAcquire(&Insert->insertpos_lck); bytepos = Insert->CurrBytePos; @@ -1586,6 +1593,10 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto) if (insertingat != InvalidXLogRecPtr && insertingat < finishedUpto) finishedUpto = insertingat; } + + finishedUpto = + pg_atomic_monotonic_advance_u64(&XLogCtl->logCopyResult, finishedUpto); + return finishedUpto; } @@ -1727,13 +1738,24 @@ WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, { char *pdst = dstbuf; XLogRecPtr recptr = startptr; + XLogRecPtr copyptr; Size nbytes = count; if (RecoveryInProgress() || tli != GetWALInsertionTimeLine()) return 0; Assert(!XLogRecPtrIsInvalid(startptr)); - Assert(startptr + count <= LogwrtResult.Write); + + /* + * Caller should ensure that the requested data has been copied to WAL + * buffers before we try to read it. + */ + copyptr = pg_atomic_read_u64(&XLogCtl->logCopyResult); + if (startptr + count > copyptr) + ereport(ERROR, + errmsg("request to read past end of generated WAL; requested %X/%X, current position %X/%X", + LSN_FORMAT_ARGS(startptr + count), + LSN_FORMAT_ARGS(copyptr))); /* * Loop through the buffers without a lock. For each buffer, atomically @@ -2571,13 +2593,19 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible) { XLogRecPtr Flush; XLogRecPtr Write; + XLogRecPtr Copy; Flush = pg_atomic_read_u64(&XLogCtl->logFlushResult); pg_read_barrier(); Write = pg_atomic_read_u64(&XLogCtl->logWriteResult); + pg_read_barrier(); + Copy = pg_atomic_read_u64(&XLogCtl->logCopyResult); /* WAL written to disk is always ahead of WAL flushed */ Assert(Write >= Flush); + + /* WAL copied to buffers is always ahead of WAL written */ + Assert(Copy >= Write); } #endif } @@ -4951,6 +4979,7 @@ XLOGShmemInit(void) SpinLockInit(&XLogCtl->Insert.insertpos_lck); SpinLockInit(&XLogCtl->info_lck); + pg_atomic_init_u64(&XLogCtl->logCopyResult, InvalidXLogRecPtr); pg_atomic_init_u64(&XLogCtl->logWriteResult, InvalidXLogRecPtr); pg_atomic_init_u64(&XLogCtl->logFlushResult, InvalidXLogRecPtr); pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr); @@ -5979,6 +6008,7 @@ StartupXLOG(void) * because no other process can be reading or writing WAL yet. */ LogwrtResult.Write = LogwrtResult.Flush = EndOfLog; + pg_atomic_write_u64(&XLogCtl->logCopyResult, EndOfLog); pg_atomic_write_u64(&XLogCtl->logWriteResult, EndOfLog); pg_atomic_write_u64(&XLogCtl->logFlushResult, EndOfLog); XLogCtl->LogwrtRqst.Write = EndOfLog; diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h index ff47782cdb..78987f3154 100644 --- a/src/include/port/atomics.h +++ b/src/include/port/atomics.h @@ -570,6 +570,42 @@ pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_) return pg_atomic_sub_fetch_u64_impl(ptr, sub_); } +/* + * Monotonically advance the given variable using only atomic operations until + * it's at least the target value. Returns the latest value observed, which + * may or may not be the target value. + * + * Full barrier semantics (even when value is unchanged). + */ +static inline uint64 +pg_atomic_monotonic_advance_u64(volatile pg_atomic_uint64 *ptr, uint64 target_) +{ + uint64 currval; + +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + + currval = pg_atomic_read_u64_impl(ptr); + if (currval >= target_) + { + pg_memory_barrier(); + return currval; + } + +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(&currval, 8); +#endif + + while (currval < target_) + { + if (pg_atomic_compare_exchange_u64_impl(ptr, &currval, target_)) + break; + } + + return Max(target_, currval); +} + #undef INSIDE_ATOMICS_H #endif /* ATOMICS_H */ -- 2.39.2 --faz4ffo26psjwnc7--