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 1vYnsD-00Ebv6-2a for pgsql-docs@arkaria.postgresql.org; Thu, 25 Dec 2025 16:07:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vYnsC-007vky-2L for pgsql-docs@arkaria.postgresql.org; Thu, 25 Dec 2025 16:07:33 +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.96) (envelope-from ) id 1vYnsC-007vko-1X for pgsql-docs@lists.postgresql.org; Thu, 25 Dec 2025 16:07:33 +0000 Received: from mail-yw1-x112d.google.com ([2607:f8b0:4864:20::112d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vYnsA-002nQT-1D for pgsql-docs@lists.postgresql.org; Thu, 25 Dec 2025 16:07:32 +0000 Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-78f99901ed5so59331507b3.3 for ; Thu, 25 Dec 2025 08:07:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766678848; x=1767283648; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=gwzZ9QTTe+tucT/CUd+YX6EEkQZMgr+0dCF/7aUhBdc=; b=NHH2RdAiQM3rMQBV5OtwT7fZtq0f685Rl90qCnYloZ0A+18FdWT25AXqzFqee+ZT2f zCrpzUok0XTKd9o73deDQsKpHxYeaUgdHmpSEZDB27w1u7ptDTmDiu5r5NjFIFvwnaFF n7bNCSxbpTGbi87hzVe8uG8rKePte9vFr4RJD918ywosG5uuNff4wG4uNwUYwmXk75bs lhqK385r0zxxo0uXoMBjzBKgAHGTl0Zw3qmVsDYWwFw4wtZn5lAKqAT0AjXFTZUqdHPr jooGEAlqoHeNpgrsm9pQqiewVy5a3ILe7KOdhb+N73kAQwCQ5YuJ6K+HVdtb/KnNz/SE 409w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766678848; x=1767283648; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gwzZ9QTTe+tucT/CUd+YX6EEkQZMgr+0dCF/7aUhBdc=; b=sAeb68vqgPaFDhx4RBemrZc9Ij5ac6NgNJCzLZpzKxagq5BS7mlLnOhkKVlzb5/aTf jXJZDGjcivsWoieqnj63jAfh5t7HHITdd96jIENoRv/6BGZa1qwlqRA3h0yr0OMaCmvY QHx+OThPggdtRi1WNatPMBjFMUvXLRLdjksiW1DhJAyyfjqw5/jP7Axsx1g3nmOdJjIJ aQrpVZw6GReCoNLUC9FnhdTkyHk/Xg42hRa+cYlP488+3RRcZpo9fWdl0DDYlcvgLkDh CWVP78HDkmbTpNPxpSTTasEAUtUp3opm7CzrCNdpOgZtEn64294TX1wZ3iHnM1Cwba9p 0Vrg== X-Forwarded-Encrypted: i=1; AJvYcCV2QbWHYx6LzNnkLUsO3OrRtM8KqhHWKI5m5toi1Osm6uSDYM7kAUaCnm36EUV6IqOeuyHfr9iqXbFM@lists.postgresql.org X-Gm-Message-State: AOJu0YztvI9v7vqtJUcI00OHMSwKNGhA1JBG2b4jjnlxxDUZ/bzRn7ro k113flUZupojx+croPwiIqh3PVvTvDi8+nBu/i95XgWO3rkLXaEeQN8FbemjKLWqyeOSvcBWBog /qO6+3Owku3wDwabx4RmCxhHRf+Nxxo/CZSVx X-Gm-Gg: AY/fxX5+FKk862QFzYJg3ya0hGsrkVWlW5h+rnK7/CtcGfaGlAYusX0w+dvYAy66VQq zeHtfa7DAB5jItBCNgjAjKnky6UvfY7ErkWlKpvQPtdu7f6zjYOpshpqX3LcUtBdzxlWg/k7ZID D50JXY9li6TaM6rJ8vu0t+ut7N0VS5znovO7zlN6FYW1YBjicVDU8UxI7qoFdG/a6VJ55yuq2ui dUG3e3fGHAgkwYJtr66JxjzvXS9XRpMDdTjzuB3qXAXfQdT42GT+Lg95IpsbLk5OPslGzeqAr4T yeqZ4MhZGSgrQg9uLaFc X-Google-Smtp-Source: AGHT+IH1T5J/dq1tMb4Snzr4Edc24+8dYyRoU2KHkiGlao0s4hvwFk10HWXW4crDiYOQQ8eqsoEko7YyWrIocs/W9Hw= X-Received: by 2002:a53:6912:0:b0:645:5d62:dd8 with SMTP id 956f58d0204a3-6466a8f31a3mr12595312d50.50.1766678848442; Thu, 25 Dec 2025 08:07:28 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Bernice Southey Date: Thu, 25 Dec 2025 16:06:52 +0000 X-Gm-Features: AQt7F2r4_LGmasSIMIBADOYSPIFG_N-z0HVGBX1xqOrxYrGXgJAI5-lsw8LDaRc Message-ID: Subject: Re: More guidance on ctid To: Robert Treat Cc: Bruce Momjian , pgsql-docs@lists.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 Robert Treat wrote: > I think there were multiple goals at play, but IMHO they resulted in > an example that was too clever by half. While I have used multiple > versions of the technique they were trying to highlight myself, I > think it is out of place to add such complex examples in the > documentation where we are relying on the behavioral side-effects > (locking and ordering) of what is essentially an implementation detail > (ctid) and a detail which we really do not recommend users interact > with in any general way. Thanks for this. Now I see why trying to fix these examples is so hard. They're obviously in the wrong place. Like you, I use this technique extensively, with and without ctid, and so I fully agree with the patch writer's aim. As I understand, it's to encourage batching for the performance benefits, how to resolve the inevitable deadlocks, and the added boost of ctid. What if we remove the examples from update and delete completely? Instead we create a new subsection in the Performance Tips chapter called Batching. This keeps all this good advice together, in a place people like me, who wanted this guidance, will go looking. This is preferable to splitting it up into unread unrelated corners of the docs. The Batching doc could be the current UPDATE doc text expanded. It can properly explain the locking options, it can briefly explain what ctid is, why it's fast, and how to use it safely with locks. I'd also like to propose including another batching trick in this new section: using copy to populate reusable session temp tables for batch processing. I expect there are other useful batching patterns community members can contribute in future. I also considered a new "Updates" section in Performance Tips, a bit like the populating a database section. But this would need lots of other additions (like minimising updates, checking if a record is actually changed, HOT updates, truncating partitions....), and it could become incohesive. I'm sure there's other potential places I'm unaware of. Unfortunately I was wrong about the examples in UPDATE and DELETE being a safe use of ctid because they're called repeatedly - the final update/delete calls aren't safe. The examples as written have the same problem they describe for skip locked, i.e. a final execution is needed for any missed rows. Using a select for update wait lock, with a ctid self-join, is the equivalent of "wait skip". Thanks, Bernice