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.96) (envelope-from ) id 1w7rKF-005ldl-0E for pgsql-hackers@arkaria.postgresql.org; Wed, 01 Apr 2026 08:53:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w7rKD-00GFsz-1h for pgsql-hackers@arkaria.postgresql.org; Wed, 01 Apr 2026 08:53:21 +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.96) (envelope-from ) id 1w7rKD-00GFsr-0R for pgsql-hackers@lists.postgresql.org; Wed, 01 Apr 2026 08:53:21 +0000 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w7rKB-000000026xY-3Hsk for pgsql-hackers@lists.postgresql.org; Wed, 01 Apr 2026 08:53:20 +0000 Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-82748257f5fso455545b3a.1 for ; Wed, 01 Apr 2026 01:53:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775033598; x=1775638398; darn=lists.postgresql.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=I+f3rRWLf2vbWYiAp91kHRIIES3kiiEtzTkFQzDq8Ls=; b=GrstgMJaqjo3VMA8Prlcq0rjjlkuvqME5Tha9bB6L9ZfoYpNMBtS2DPn6m6lIMALc7 T+yvn9ABxkMQ5PvgO6FvjjIK4tkMWi8oO/0ybEhaODUsohHqQ8ZhHC0zZ1j77tFKnqwv dWYT67lj344tv3TKN1AoB5IWshP9RaYcuAsNwpm7QagUQsJI0Wsx5s7DVAfQMhvp50fY OgAfKnnz3HQ1YffARvNmYaT81NnSll6+6DftrLQH6WCSOMHt9ONr4W7pk9StT+jytzui Ct1YrkUE1LPZv99MUC0hV7w0L54GVcI/SDvaL9icxIfA1HfzdkyeiDHVLgg95E7whvcD w28g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775033598; x=1775638398; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=I+f3rRWLf2vbWYiAp91kHRIIES3kiiEtzTkFQzDq8Ls=; b=H3zlEIYnCS9vxqOfBNWQTj/AeptwQSorHm+J8UYGNIBoCQo8WY6UgvekUzNk+ewvQe udam82Iy4DUShqw/fSQ/AoUx2CY7m4zZ32SVBsfbKrn0IfYFQrBBsCNtAgXcCOVMmdsV Zut5Lr6l9Hx7beCeRI2bFrRRj99D9ZKaACHijFPddMPkzKaE2sS9+0CDvuKhasBfgMSb DuoTNqvN/N3zq2PW+I+EArGtm70wUcMZ3Kt7Hpq/4xQzL1kpstNDro7Z3XzUXuW5DrT9 w50kLQWEnl8pFoNMb2epxu1hHBEDM2R8CaNKF4Nwu8IInjqJNC684smzdQPxDXldOZ/0 wpVw== X-Gm-Message-State: AOJu0YxhEZGl8VJ8dMC7XKgC6gBBX97+Frf2vXRLeq0eJIpB6deRmY2N PE4385JUweLU+IBs+fhLpxrQJEWse7IN0gmgl3O0hBDqEMxQ7e1aJpGIPQ9mFAF9v6g= X-Gm-Gg: ATEYQzxaVlev2fy0XsJFSZzUinqAzPNJH+lETDl+zYhtlPnLX1PWUMjmNvJHq/kla95 BC8ytM1reP+cuKYAw15ihuGYTbxmFBb0jWMePMrAq94f9bSRTnGxu6VRRMgbZMJR068uVN4Ojst 88zkQTUl7uYCYDIn8JJ0CEh/7fK4eYWyem9FGLTWJdBagtTE/QLOp4Maych17oeA2sJwRwNosA5 ylQrCB90ET+1mog+NhaR3AgizSacohO48EBaNJI1LZ9vwBp1GBHfHXw13doxeXkrEp/RB80vQf/ TPJCouPE/HHsFraERoJI1D6qbY+qvoePH9V1s0tSlIQabTF8yBWKuNFyv6LkR44B6LssEo0drnp RRf8sYE9wYX1GYhSPizLPxwsq0ewAUwnQg7LZLbucuya15W0Bc/hJIyxBb+IPAYZ0TM4kVlAkIa 73ZtlZWiEXJ6iWsc9R6NDxTc/yngc= X-Received: by 2002:a05:6a20:e290:b0:39b:ff20:f4e5 with SMTP id adf61e73a8af0-39edbd20cd6mr6782450637.12.1775033597966; Wed, 01 Apr 2026 01:53:17 -0700 (PDT) Received: from localhost ([91.243.81.108]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c769179e497sm11367731a12.21.2026.04.01.01.53.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Apr 2026 01:53:16 -0700 (PDT) Date: Wed, 1 Apr 2026 16:53:09 +0800 From: Adam Lee To: pgsql-hackers@lists.postgresql.org Cc: Michael Paquier Subject: [PATCH] Fix minRecoveryPoint not advanced past checkpoint in CreateRestartPoint Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="IxHwtWaH/DA3wSaA" Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --IxHwtWaH/DA3wSaA Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi hackers, I ran into this while working on recovery pre-check logic that relies on pg_controldata to verify whether replay has reached a specific restore point. Reproducer: ``` -- on primary: CHECKPOINT; SELECT pg_create_restore_point('test_rp'); -- recover with: -- recovery_target_name = 'test_rp' -- recovery_target_action = 'shutdown' -- after recovery shuts down: pg_controldata shows minRecoveryPoint 104 bytes behind pg_create_restore_point's return value (104 bytes = one RESTORE_POINT WAL record). ``` My RCA: When recovery_target_action=shutdown triggers, the checkpointer performs a shutdown restartpoint via CreateRestartPoint(). If a CHECKPOINT record was replayed shortly before the recovery target, CreateRestartPoint advances minRecoveryPoint to the end of that CHECKPOINT record. However, any no-op records replayed after the CHECKPOINT (such as RESTORE_POINT) do not dirty pages, so the lazy minRecoveryPoint update that normally happens during page flushes never fires for them. As a result, minRecoveryPoint in pg_control ends up behind the actual replay position. My Fix: The attached patch fixes this by reading the current replay position from shared memory after advancing minRecoveryPoint to the checkpoint end, and advancing further if replay has progressed past it. This is safe because CheckPointGuts() has already flushed all dirty buffers and the startup process has exited, so replayEndRecPtr is stable and all pages are on disk. -- Adam --IxHwtWaH/DA3wSaA Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=0001-Fix-minRecoveryPoint-not-advanced-past-checkpoint-in.patch