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.98.2) (envelope-from ) id 1xB640-000000030De-11w1 for pgsql-hackers@arkaria.postgresql.org; Mon, 28 Sep 2026 07:46:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xB63x-00000008GFl-2ZNk for pgsql-hackers@arkaria.postgresql.org; Mon, 28 Sep 2026 07:46:13 +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.98.2) (envelope-from ) id 1xB63x-00000008GFc-1K1G for pgsql-hackers@lists.postgresql.org; Mon, 28 Sep 2026 07:46:13 +0000 Received: from mail-wm2-x11.google.com ([2a00:1450:4864:31::11]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1xB63u-00000001e6i-47Tl for pgsql-hackers@lists.postgresql.org; Mon, 28 Sep 2026 07:46:12 +0000 Received: by mail-wm2-x11.google.com with SMTP id 5b1f17b1804b1-49ffbd83a92so11430975e9.0 for ; Mon, 28 Sep 2026 00:46:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790581569; x=1791186369; darn=lists.postgresql.org; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:from:to:cc:subject :date:message-id:reply-to:content-type; bh=GKv/p7p/mYm/QbNAu5X+CfsYOlqm0wYJutIReVBvuDk=; b=WJO7s8K8ssPcBdmayD84cu6QBtF6wPgi6A4p0ebfEbIX4xLMDel3LY655KPtmrsPjT thux2B3I9eUeLkai0aKHxQoePP1uusK2sZZ02BJbFXPfiXtnmXAL2GuPICpOI9BuBvHo X7nHu8UHqNZP6jy59gRsEoGQ0igfHFq4ab+XdnukXH8fFQfr7azEZidpgw4dGjQJYYnn 5EQ68KfcT+nY09dtlhqUBelf3fDO+eNf7OdlfVQoodFe5McAVIT5OO98qvG4o2g1phGp PXV1st5S7shcHmyGdOIXdfVM+4Fc4P2Vh2etM7OtjwsVDjkR10GW7LyuTaUFj0OT7vCM 2XUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790581569; x=1791186369; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GKv/p7p/mYm/QbNAu5X+CfsYOlqm0wYJutIReVBvuDk=; b=BiTgrx2jp3oTsHdg2ufRjdpmM4871NM7wForQhAyuIMkXcBHssvv5lWro1B9zIOGia sOn2pOmh74udNbPKyTwDxlZs2VebQEwKZ5Ru7JF2cZUWYmpME+jNp1ocDLWigiqe2/+U eWeWtTaf9qnEFjKExazuQmwPweyb6MshiOmxtMFoD0xFIXumAnPcF9TOTYIgYzXoMw9L BDbe2CgHwU5r1z3Gb1+O6uxK0l5KAj5063MJWbCYe0Vzicwu6Eo6wajD4h72FRpZbXGu 5iXiRTze2A0XGwO6VBImj49yFVcpu+fxqEHfpf+drUJjgqmGqfgMyoxDvzI67/L3Uif/ 7GiQ== X-Forwarded-Encrypted: i=1; AKwUvBx9DS4DIGgA5AdPbVJCiD8IMWZDMJY3p2NcFhtoTxUq5KrnGNn06qczLdZ0v+RdPMZ6x811ksGODswW13L8@lists.postgresql.org X-Gm-Message-State: AFuF++mFPicySSRomqpD/tEbkf24vL75GJZdwA/hy4Z7fgSy0NBRz111 sF8VWFbbstBqnqzAFsIiKnfWtTJlRR7oJjrj5O63ErpHbfKDWrs1MtiK X-Gm-Gg: AYBFou0Arw1+Yp5ILkETR7v08RHZxZL9zwuPRFTdji5Zdbjdk86vO1K/z9z5XJp2rPB ubZj51N7gPTnCuD567At4qduTohOFDE6IAL3SnfVmXg4DV864mpJW8P7lpgqmXH+6tkIlmh/ctm VXrBL74HjFNep3J5bucKmaVnQ8PBMTynQvmqWWww4bgm9UT4gEroMDH+k5a/FmhBR+27ZgP841i zK4amtLRVuEDnFn/uTGU/y8d0dVHYyhshES6NL0fw6kNnUz2aI6HdrexmEnE15/LYmAeDysFu1Q lzYAY29jfwltrt+OLhfY/XrvH6EfdCz+p9h01z/75Q8wvH2hZPXdqJ61cAqW59ZN2pMlAffnacg wW5m6M/lMiFQZEzIjgxcbpeZipcnPukxX0TzIW2Kgbz3NNPWZTTae5QY1UWxd9rPCclPylNUuWO wcX4TJXLsUf020G8fRqYzelGN0prWlkJ/Mf+TljYFQ161ivEmy4O4qW4YMezi1Ha3pcCp4Q44CE rpK/Bc4jBwaybXGKEoD3wbUZaqIz8dClzzEIi7Yg7nVGvOMDHA4XWj8+A== X-Received: by 2002:a05:600c:198a:b0:499:b65e:49c9 with SMTP id 5b1f17b1804b1-49fe66d2d24mr220940905e9.10.1790581568890; Mon, 28 Sep 2026 00:46:08 -0700 (PDT) Received: from bdtpg (ec2-15-237-197-144.eu-west-3.compute.amazonaws.com. [15.237.197.144]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a0017816efsm118922645e9.9.2026.09.28.00.46.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Sep 2026 00:46:07 -0700 (PDT) Date: Mon, 28 Sep 2026 07:46:06 +0000 From: Bertrand Drouvot To: Zhijie Hou Cc: shveta malik , JoongHyuk Shin , Amit Kapila , Rui Zhao , pgsql-hackers@lists.postgresql.org Subject: Re: Persist slot invalidations before publishing them Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, On Sun, Sep 27, 2026 at 10:10:33PM +0800, Zhijie Hou wrote: > When reading the patches, Thanks for looking at it! > the part that feels heavy to me is the serialization > machinery added to InvalidatePossiblyObsoleteSlot() for the two-invalidator > race - the conditional acquire of io_in_progress_lock, dropping > ReplicationSlotControlLock to wait, and the restart of the loop - plus the > caller-owns-the-io-lock contract that ReplicationSlotPersistInvalidation() > imposes on both call sites. That might look heavy but I don't think this pattern is unusual: SLRU uses the same general lock, wait, and recheck pattern, and InvalidatePossiblyObsoleteSlot() already follows that model when waiting on active_cv. > You mentioned effective_catalog_xmin, and there are similar shadow fields like > last_saved_restart_lsn. What about the same style here: keep the claim exactly > as on master - active_proc and data.invalidated set in one spinlock section - > and add a pure in-memory boolean, say invalidation_durable, set only at the > point the invalid image has actually been written and fsynced (the tail of > SaveSlotToPath(), keyed off the image just written. All consumer references to > data.invalidated (horizon computations, pg_replication_slots, slotsync's > skip/drop decisions) would consult the new flag instead; the invalidators' > mutual-exclusion check and the acquire path keep reading the cause as today. I'm not sure the alternative is lighter overall. It moves the complexity into a new intermediate slot state and requires each consumer of data.invalidated to decide whether it should also check invalidation_durable. > The new flag can be added to the padding space, so there is no change in the > size of ReplicationSlot. Yeah that look ok if, for example, we place it here: (gdb) ptype /o struct ReplicationSlot /* offset | size */ type = struct ReplicationSlot { /* 0 | 1 */ slock_t mutex; /* 1 | 1 */ _Bool in_use; /* XXX 2-byte hole */ /* 4 | 4 */ ProcNumber active_proc; /* 8 | 1 */ _Bool just_dirtied; /* 9 | 1 */ _Bool dirty; /* XXX 2-byte hole */ /* 12 | 4 */ TransactionId effective_xmin; . . . My concern is that data.invalidated would then have two roles depending on invalidation_durable. Invalidators and the acquisition path would treat a value other than RS_INVAL_NONE as an invalidation, while other consumers would do so only once invalidation_durable is set. That could be an issue for existing extensions on back branches. An extension could treat the slot as invalid while core consumers gated by invalidation_durable still treat the invalidation as not effective. So, although the ABI layout would be preserved, the semantics of an existing field would change. Thoughts? -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com