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 1sYwgP-00FKPp-BR for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jul 2024 23:55:09 +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 1sYwgN-00EytQ-7Z for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jul 2024 23:55:07 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sYwgM-00EytI-Ln for pgsql-hackers@lists.postgresql.org; Tue, 30 Jul 2024 23:55:06 +0000 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sYwgH-002Ktz-E9 for pgsql-hackers@postgresql.org; Tue, 30 Jul 2024 23:55:03 +0000 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-70d19c525b5so3478469b3a.2 for ; Tue, 30 Jul 2024 16:55:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1722383698; x=1722988498; darn=postgresql.org; h=user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=cLZzH65FlfgtI+CEgS9QjaGqbwRwBLG5OvyDlooQ8cE=; b=XAoLyBD3Jl25J7R15sEmWld8YSC5/buqfJWSJQBXdNZphj+NhSDhyGlkoMnbg8I8tm jBTRBd+b9xULGSzN33Iw76LTIsTA7o0+wSipF5vki/FjUP5iwEB3IGO0OlNi91BYPOsH 5EIYmmdXSJEcg7otXFCzhf5u7Bq1Yk5IPRlZ4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722383698; x=1722988498; h=user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=cLZzH65FlfgtI+CEgS9QjaGqbwRwBLG5OvyDlooQ8cE=; b=NzD1shaFcvY5EBS4i0s6kXmXYq7ZwGEkw7g7Wb7dKR9T38lRRnNPXJ2+xnHdTj4uOj v8vB72mnweuaIBcI76ZcglrcOTfp7wxYa2UKhkEHskmo35Q7yLMrn/zSB8lAjQJzhTl/ 0hedt7ErTFDI+5CAEHV/LZP+o94gwM1yDN8tUg/4EE9T/WGH4TRphYoq8mux+6QNwIXg jyLgM5FnpzwfU4VLisI16RlKFatfmG+0+igKa8eJpijndi+qUs1HmVfREKl9mgbJwEXd eYwpfb/e+HJ7U53JGsKFZ9MpyNEmcpC2kcmKf+FcDzv3sYdNB/7SDXnl+liKiJ75Fkm/ NqXw== X-Forwarded-Encrypted: i=1; AJvYcCVV1kX5uEyh5vDllrBB1xKcbY23uNiVFaxfyUfu46wfYqfBpicZRkb2rqzoGtQ1NS3aEp8rnZZKmMOasohc3uu2hVgB5WVQLnQvFSSu X-Gm-Message-State: AOJu0Ywo/GQYJV0T+L1Ycr0QWL6hvSMvOwGgP8+7KtGO6kberkqwDUT/ x0CP/oTrwf7/gTAtZsFszW+Rs8he6nMuqWgNKEfovtA0OVWNlBHT8MQZ6ztj0g== X-Google-Smtp-Source: AGHT+IFtt1XP0ugb8cOl/9H8KiprWESQA0dw3poEsx5PbSLEVwjun7E39zPernhHzHlaTzmjecFqwg== X-Received: by 2002:a05:6a20:72a2:b0:1c4:b302:ad14 with SMTP id adf61e73a8af0-1c4b302b300mr10796894637.24.1722383698284; Tue, 30 Jul 2024 16:54:58 -0700 (PDT) Received: from google.com ([2600:1702:a20:5750::48]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fed7edd90dsm108056485ad.161.2024.07.30.16.54.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Jul 2024 16:54:57 -0700 (PDT) Date: Tue, 30 Jul 2024 16:54:55 -0700 From: Noah Misch To: Thomas Munro Cc: Andres Freund , Tom Lane , Nathan Bossart , Melanie Plageman , Michael Paquier , Fujii Masao , "pgsql-hackers@postgresql.org" Subject: Re: race condition when writing pg_control Message-ID: <20240730235455.08.nmisch@google.com> References: <20240516183558.GA1620903@nathanxps13> <2136775.1715885450@sss.pgh.pa.us> <20240516185805.hnbt2tr23q7xbx3m@awork3.anarazel.de> <2138498.1715886091@sss.pgh.pa.us> <20240516190744.6beu43cjdvrml6uw@awork3.anarazel.de> <20240712114322.08.nmisch@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/2.2.12 (2023-09-09) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, Jul 15, 2024 at 03:44:48PM +1200, Thomas Munro wrote: > On Fri, Jul 12, 2024 at 11:43 PM Noah Misch wrote: > > On Sat, May 18, 2024 at 05:29:12PM +1200, Thomas Munro wrote: > > > On Fri, May 17, 2024 at 4:46 PM Thomas Munro wrote: > > > > The specific problem here is that LocalProcessControlFile() runs in > > > > every launched child for EXEC_BACKEND builds. Windows uses > > > > EXEC_BACKEND, and Windows' NTFS file system is one of the two file > > > > systems known to this list to have the concurrent read/write data > > > > mashing problem (the other being ext4). > > > > > First idea idea I've come up with to avoid all of that: pass a copy of > > > the "proto-controlfile", to coin a term for the one read early in > > > postmaster startup by LocalProcessControlFile(). As far as I know, > > > the only reason we need it is to suck some settings out of it that > > > don't change while a cluster is running (mostly can't change after > > > initdb, and checksums can only be {en,dis}abled while down). Right? > > > Children can just "import" that sucker instead of calling > > > LocalProcessControlFile() to figure out the size of WAL segments yada > > > yada, I think? Later they will attach to the real one in shared > > > memory for all future purposes, once normal interlocking is allowed. > > > > I like that strategy, particularly because it recreates what !EXEC_BACKEND > > backends inherit from the postmaster. It might prevent future bugs that would > > have been specific to EXEC_BACKEND. > > Thanks for looking! Yeah, that is a good way to put it. Oops, the way I put it turned out to be false. Postmaster has ControlFile pointing to shared memory before forking backends, so !EXEC_BACKEND children are born that way. In the postmaster, ControlFile->checkPointCopy->redo does change after each checkpoint. > The only other idea I can think of is that the Postmaster could take > all of the things that LocalProcessControlFile() wants to extract from > the file, and transfer them via that struct used for EXEC_BACKEND as > individual variables, instead of this new proto-controlfile copy. I > think it would be a bigger change with no obvious-to-me additional > benefit, so I didn't try it. Yeah, that would be more future-proof but a bigger change. One could argue for a yet-larger refactor so even the !EXEC_BACKEND case doesn't read those fields from ControlFile memory. Then we could get rid of ControlFile ever being set to something other than NULL or a shmem pointer. ControlFileData's mix of initdb-time fields, postmaster-start-time fields, and changes-anytime fields is inconvenient here. The unknown is the value of that future proofing. Much EXEC_BACKEND early startup code is shared with postmaster startup, which can assume it's the only process. I can't rule out a future bug where that shared code does a read that's harmless in postmaster startup but harmful when an EXEC_BACKEND child runs the same read. For a changes-anytime field, the code would already be subtly buggy in EXEC_BACKEND today, since it would be reading without an LWLock. For a postmaster-start-time field, things should be okay so long as we capture the proto ControlFileData after the last change to such fields. That invariant is not trivial to achieve, but it's not gravely hard either. A possible middle option would be to use the proto control file, but explicitly set its changes-anytime fields to bogus values. What's your preference? I don't think any of these would be bad decisions. It could be clearer after enumerating how many ControlFile fields get used this early.