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 1tIsoE-00HFcV-5q for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Dec 2024 17:05:06 +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 1tIsoB-001U0I-Ll for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Dec 2024 17:05:04 +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 1tIsoB-001Tzy-A7 for pgsql-hackers@lists.postgresql.org; Wed, 04 Dec 2024 17:05:04 +0000 Received: from mail-ed1-x536.google.com ([2a00:1450:4864:20::536]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1tIso9-0012VC-Oz for pgsql-hackers@postgresql.org; Wed, 04 Dec 2024 17:05:03 +0000 Received: by mail-ed1-x536.google.com with SMTP id 4fb4d7f45d1cf-5d0cd67766aso6027390a12.2 for ; Wed, 04 Dec 2024 09:05:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733331900; x=1733936700; darn=postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=1cg3KOktpBbCfUtJIBcEdn14TXcuDwZ9vb/FnL6A0BY=; b=bjqxd5CRF8UZgtRazYB8PWKJgeU5ZLwgcz9gCqyj26RUohtsTRU0ZdLxCc8MEmSFIV rIzlmrmRUj7pJVk1K05NDAIBoZ9OrcqgH3o8G74wdXtyFLI8pgNaEYaoP0xHfSVb4G8r 6LZpquOU1aMW2LBqB8ps8SxFPRx/kw2CdHNpcDQJpDFw6skIR2R9AQtRyyAvP/e/i/BP Z05oo18zInxrlUvCy+fLUQpkO9Z9zKm70TEUt+uxZ2KNue72+hV7yzd4j8mPhe66lIF2 G2NPOpxtG/UynS2DNdpYlQ+c05VcARABegQ+1DvrXINDzH5HVeo49D5R6MFpEXyrlnoF iLpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733331900; x=1733936700; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=1cg3KOktpBbCfUtJIBcEdn14TXcuDwZ9vb/FnL6A0BY=; b=sWQTVknHedLDz6g92wt6WAXVMl6gc2Hb34YOrYiSHh3m8g8uyra3Mu55LeUjcjPk+n pNOCr+0Z2g4Ii1zGmfXbZg0/00eFcirxkPjyy8KUUz1hvTmJOHHixO4W4HW5vZANaSg5 tL4+aRoq0d/MYHiujYE4JOpY9uvftjTDvYweJoj1tgOUzWJuCo2NWG5Rer2ml4yiwZ3W TskMibySxaD1fBPjx5RcS/+UlvjKKr2usRqFTPbfgZpajnY3gNuLztIRyUiYR/m0mS0A h9yrxljosz3H/bst2/J67mCOss74yzwdrWJ2mlrW1ktijUiDPpzAVjXj1wV7VNxbxbLP 6zfQ== X-Gm-Message-State: AOJu0Yxcdt4ibZmHo4/39yQg2dKMN8z6SyqFyg5RUUsuGrBDs1rObd2h lK9//3apOi+xE+TnaOW4hEKvEeX/6CWz0sSSxl1C0QgbZVkrL7MGI2ikL60w4PinMEmcmCab6q6 DWgMJCIuHJTv4hIZhlgm8mKOMmPHUM4q3 X-Gm-Gg: ASbGncvwhfbuue+qSjr11c+GrKS7x8zlqth4hgMBgnYU6T8jHT3NrlzbyABzqFkrm4+ 4vFhRlP0el5CixIJNZpU09cEKIXYZspw= X-Google-Smtp-Source: AGHT+IEn8iOavIBPPFrRgvuuR70eguf4QNwpv3vHrCcliFDXauAy0hDGnWwjapvwE6aaxrx8IJqvWWJBb1SkTMynXIE= X-Received: by 2002:a17:906:318d:b0:aa4:fc7c:ea6d with SMTP id a640c23a62f3a-aa5f7d15a96mr636946166b.17.1733331899519; Wed, 04 Dec 2024 09:04:59 -0800 (PST) MIME-Version: 1.0 From: Robert Haas Date: Wed, 4 Dec 2024 12:04:47 -0500 Message-ID: Subject: deferred writing of two-phase state files adds fragility To: "pgsql-hackers@postgresql.org" Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Let's suppose that you execute PREPARE TRANSACTION and, before the next CHECKPOINT, the WAL record for the PREPARE TRANSACTION gets corrupted on disk. This might seem like an unlikely scenario, and it is, but we saw a case at EDB not too long ago. To a first approximation, the world ends. You can't execute COMMIT TRANSACTION or ROLLBACK TRANSACTION, so there's now way to resolve the prepared transaction. You also can't checkpoint, because that requires writing a twophase state file for the prepared transaction, and that's not possible because the WAL can't be read. What you have is a mostly working system, except that it's going to bloat over time because the prepared transaction is going to hold back the VACUUM horizon. And you basically have no way out of that problem, because there's no tool that says "I understand that my database is going to be corrupted, that's ok, just forget about that twophase transaction". If you shut down the database, then things become truly awful. You can't get a clean shutdown because you can't checkpoint, so you're going to resume recovery from the last checkpoint before the problem happened, find the corrupted WAL, and fail. As long as your database was up, you at least had the possibility of getting all of your data out of it by running pg_dump, as long as you can survive the amount of time that's going to take. And, if you did do that, you wouldn't even have corruption. But once your database has gone down, you can't get it back up again without running pg_resetwal. Running pg_resetwal is not very appealing here -- first because now you do have corruption whereas before the shutdown you didn't, and second because the last checkpoint could already be a long time in the past, depending on how quickly you realized you have this problem. Before 728bd991c3c4389fb39c45dcb0fe57e4a1dccd71, things would not have been quite so bad. Checkpoints wouldn't fail, so you might never even realize you had a problem, or you might just need to rebuild your standbys. If you had corruption in a different place, like the twophase file itself, you could simply shut down cleanly, remove the twophase file, and start back up. I'm not quite sure whether that's equivalent to a forced abort of the twophase transaction or whether it might leave you with some latent corruption, but I suspect the problems you'll have will be pretty tame compared to what happens in the scenario described above. Just to be clear, I am not suggesting that we should revert that commit. I'm actually not sure whether we should change anything at all, but I'm not very comfortable with the status quo, either. It's unavoidable that the database will sometimes end up in a bad state -- Murphy's law, entropy, or whatever you want to call it guarantees that. But I like it a lot better when there's something that I can reasonably do to get the database OUT of that bad state, and in this situation nothing works -- or at least, nothing that I could think of works. It would be nice to improve on that somehow, if anybody has a good idea. -- Robert Haas EDB: http://www.enterprisedb.com