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 1tTgw8-008Hp9-KL for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Jan 2025 12:37:57 +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 1tTgv8-0017pR-3m for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Jan 2025 12:36:53 +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 1tTgv7-0017my-Kk for pgsql-hackers@lists.postgresql.org; Fri, 03 Jan 2025 12:36:53 +0000 Received: from mail.postgrespro.ru ([93.174.131.139]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tTgv3-001t7p-2q for pgsql-hackers@postgresql.org; Fri, 03 Jan 2025 12:36:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1735907806; bh=Dij1Rs10+m3w32KArGaNGMn1zkxfEINMwfcxNYNNLV4=; h=Message-ID:Date:User-Agent:Subject:To:References:From:In-Reply-To: From; b=65EVD/BnWK7ZEKuWwm2t4WkDoZs2JUTdax+XxTsZ4DwyK3l2E/CiI+5qwmd98uc28 lv8WnvJB3ZGHQrqzkeS89nfX+kzBh/qUdLK0G7OBBGQO5MYx556RDhdC7tc4Ijs3Yf +o13KV4cDIamOo7kX1JPbaS0TGr5SDwrk7ogTy6ky6NQ2QdNVOxg13oR2TDnIkSQo9 xLJYgGALaMx8uxYNfBsU2cGRJlk7hw/SWpTCg9yo8hUTt395lLvfE/Z29LBI/o48Qm n6gwiTP9h0A6q3L3xbhIZ4dHZRskx7yNPcMDzxO9dj+RfytnFGd7FwhTxvkdhgN9Gj 0aX6vHq5xavcw== Received: from [172.30.48.78] (unknown [172.30.48.78]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: y.sokolov@postgrespro.ru) by mail.postgrespro.ru (Postfix/465) with ESMTPSA id D09E660189; Fri, 3 Jan 2025 15:36:45 +0300 (MSK) Message-ID: <421eede5-0ecf-421f-9b56-f05d4f51e099@postgrespro.ru> Date: Fri, 3 Jan 2025 15:36:45 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC] Lock-free XLog Reservation from WAL To: "Zhou, Zhiguo" , "pgsql-hackers@postgresql.org" References: Content-Language: en-US From: Yura Sokolov In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-KSMG-AntiPhishing: NotDetected X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.1.0.7854, bases: 2025/01/03 11:33:00 #26941080 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk 02.01.2025 10:05, Zhou, Zhiguo wrote: > Hi all, > > I am reaching out to solicit your insights and comments on a recent proposal regarding the "Lock-free XLog Reservation from WAL." We have identified some challenges with the current WAL insertions, which require space reservations in the WAL buffer which involve updating two shared-memory statuses in XLogCtlInsert: CurrBytePos (the start position of the current XLog) and PrevBytePos (the prev-link to the previous XLog). Currently, the use of XLogCtlInsert.insertpos_lck ensures consistency but introduces lock contention, hindering the parallelism of XLog insertions. > > To address this issue, we propose the following changes: > > 1. Removal of PrevBytePos: This will allow increments of the CurrBytePos (a single uint64 field) to be implemented with an atomic operation (fetch_add). > 2. Updating Prev-Link of next XLog: Based on the fact that the prev-link of the next XLog always points to the head of the current Xlog,we will slightly exceed the reserved memory range of the current XLog to update the prev-link of the next XLog, regardless of which backend acquires the next memory space. The next XLog inserter will wait until its prev-link is updated for CRC calculation before starting its own XLog copy into the WAL. > 3. Breaking Sequential Write Convention: Each backend will update the prev-link of its next XLog first, then return to the header position for the current log insertion. This change will reduce the dependency of XLog writes on previous ones (compared with the sequential writes). > 4. Revised GetXLogBuffer: To support #3, we need update this function to separate the LSN it intends to access from the LSN it expects to update in the insertingAt field. > 5. Increase NUM_XLOGINSERT_LOCKS: With the above changes, increasing NUM_XLOGINSERT_LOCKS, for example to 128, could effectively enhance the parallelism. > > The attached patch could pass the regression tests (make check, make check-world), and in the performance test of this POC on SPR (480 vCPU) shows that this optimization could help the TPCC benchmark better scale with the core count and as a result the performance with full cores enabled could be improved by 2.04x. > > Before we proceed with further patch validation and refinement work, we are eager to hear the community's thoughts and comments on this optimization so that we can confirm our current work aligns with expectations. Good day, Zhiguo. Idea looks great. Minor issue: - you didn't remove use of `insertpos_lck` from `ReserveXLogSwitch`. I initially thought it became un-synchronized against `ReserveXLogInsertLocation`, but looking closer I found it is synchronized with `WALInsertLockAcquireExclusive`. Since there are no other `insertpos_lck` usages after your patch, I don't see why it should exists and be used in `ReserveXLogSwitch`. Still I'd prefer to see CAS loop in this place to be consistent with other non-locking access. And it will allow to get rid of `WALInsertLockAcquireExclusive`, (though probably it is not a big issue). Major issue: - `SetPrevRecPtr` and `GetPrevRecPtr` do non-atomic write/read with on platforms where MAXALIGN != 8 or without native 64 load/store. Branch with 'memcpy` is rather obvious, but even pointer de-referencing on "lucky case" is not safe either. I have no idea how to fix it at the moment. Readability issue: - It would be good to add `Assert(ptr >= upto)` into `GetXLogBuffer`. I had hard time to recognize `upto` is strictly not in the future. - Certainly, final version have to have fixed and improved comments. Many patch's ideas are strictly non-obvious. I had hard time to recognize patch is not a piece of ... (excuse me for the swear sentence). Indeed, patch is much better than it looks on first sight. I came with alternative idea yesterday, but looking closer to your patch today I see it is superior to mine (if atomic access will be fixed). ---- regards, Yura Sokolov aka funny-falcon