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 1vkwh4-004thd-1Y for pgsql-general@arkaria.postgresql.org; Wed, 28 Jan 2026 03:58:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vkwh3-00H8lJ-28 for pgsql-general@arkaria.postgresql.org; Wed, 28 Jan 2026 03:58:14 +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 1vkwh3-00H8lB-0v for pgsql-general@lists.postgresql.org; Wed, 28 Jan 2026 03:58:13 +0000 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vkwh0-00000000ocq-3urZ for pgsql-general@postgresql.org; Wed, 28 Jan 2026 03:58:13 +0000 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-34c5f0222b0so3343779a91.3 for ; Tue, 27 Jan 2026 19:58:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1769572688; cv=none; d=google.com; s=arc-20240605; b=DwHfFVO6X2iBnzyTOoPEBr/4DM+l0tij9NdFsD+6S6g2uKRKAO0yMbCO0X76kbtvR+ W/8+LfccqLHzy2PN2tXUYcR0KbknYGEVDTTO3OhExbW/HPhdWVXNGuD5X9/Q6trJy6HX HSb2giUb9HH4YLDptxQbRE78ijLqUCPRm7jf6+N7z84rrRst4iKxvSqARwU9mQ7S/unV rQ/689d8wMmIaeJ/sSivIlWAc/K7lSElEAfrRF+nTSErmlsPJCBnkIsYTW7Ra0BAG+YF DLOR9UA2qFm2qLAgiIHaktR1Bryfzh5nPx2UhwHMXqSnB7zm8v9/AUoYQiB3+pNnV8pE kHSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=mX2xFl15hSL2KJT/4aDREaisB4MJ/0BHiHQz4YXcBCU=; fh=KNSq+t9BltSXFnT3Yof/aKGBtqxeA+bTALiYdvTslaY=; b=WL9jrQAd+F0kGlKtTtCBkaxi/UDCbz5A1T6JUeP7RK/vmzA9L2nKDfi4fkfaNOJtRe IWxjZlypuyVppsui6QOD5L+lKyI0uRXTK6xAvWPP03W29OYIbqS6mxFK/fIgbv/9vkY0 qNLFBPhzvrNX5L3vdYQDki5UlhATHmDGrFKiCpgu4Z3cgjBFqWlV1JWU4+O/lwTb52y/ YgpTT4eaMAzeXopkiB4sXOkdOcOrje1mGWD/19lH268Li1SkjeuYnWVWhI4yqk+zSeCC 5zSKeD8hxC5Gd0kbo7Om5iacNNSpEDKFZ+msbVzKJoHVCR0SXlpQpT/G/m4bU4OWIZ5Q Qepw==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769572688; x=1770177488; darn=postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=mX2xFl15hSL2KJT/4aDREaisB4MJ/0BHiHQz4YXcBCU=; b=eUGxVgj4aMgZ34z2zlQ5yj9tAApG40atJpm9yVZVU9IjfoNbhBeBVptI1T2cwX4bum 5nMGJjozdhlP9igzinRFfdCcClcPQM6HPuGA0bhevhxomUCHkWzla+ok2AptG0cOsugw UCkaQcAMFcwwIzJooal2N/8mPe/Cav99qJT+8pbxsS4D8STwq24wEm1J8V3aZosr9aS6 FCtYLZk10fDhEMO7Alw9pYnGBIa4UPnCaRVgUSeVjerwlB/RUvAg3B/+GRAbUdLY/fOz KClHiM98oNI2eSIFR2oEzd6exGxz0YHiP5mtqyQG5UrMtbGf3pV/PjyPdOOZjpY+CwKg GJWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769572688; x=1770177488; h=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=mX2xFl15hSL2KJT/4aDREaisB4MJ/0BHiHQz4YXcBCU=; b=aQLbdPTJN6UBL3sPXUbUhCX1pdD76jE4ztfvpRfWvDUBAHQYmH5kU7J1lCyfA35LEL UGB/qfB350OMhXBA6NuB4ee6VhAiOPKDW3L9r1wzcHXcqNZ9XSPdzqSLcKTtHESijkOo jCOfph4fLONURJH+r9fxXaqItIAdIKxRGbMJPpbvoYZzxfOab+CkQkermeRB7MMNxpPU FyTdWYBlpvBcukvYimuh4IQTIEcGy5mogecrcZ3Df+3dE2WvwSEu7OYMdfAPAila64NB np+DY3mrrf8cldKQLKWNHZscojs4e7NRxZj0P1jVs7SGtyXK1J7u1N6Wy7MX/BPySJHB jvig== X-Gm-Message-State: AOJu0YwTOVVWraLTfiWJg/8vByKRS8JlucyiFBARVgJv/ITCpF6Ds6sO zl55JgWrT2MiHHMssUl0iG7J1Gq/DZS5mk+9AW+o3Yd6L1aOSkxUPQU32hNIKxg7IfG4g+2CWDt Rq0xt6/le/3WtjY2HrmVElueszlOy6dUjnZc/ X-Gm-Gg: AZuq6aLlr9gWpur7spvBiQcWgeidZLmbIudQvN40S/S9Gt9RVGlVfcqTZwI9RgWj/QL jmtI59z4BnEd/4TEhQcQYTJ41sz+w3cEWy/g09Oj1IblcGvEhhHS6kq8Ho3syf3FO2zlYxo1JM7 nvIW4G+2pcgmLVZnoT15ZGXeIqb84GBgETpVQ+hY3Q95vzvMMYjXa5NkEyApNm8I4MnsH2fMWlC ZdXgiIMM/LN3/FW65MgTfEwHa7MHR67Ye+Rlb6miaw1qNHO4abh7D8evYInfJ5QGfini3yE X-Received: by 2002:a17:90b:1dc4:b0:34a:adf1:677d with SMTP id 98e67ed59e1d1-353fece4939mr3396328a91.9.1769572687796; Tue, 27 Jan 2026 19:58:07 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Ron Johnson Date: Tue, 27 Jan 2026 22:57:56 -0500 X-Gm-Features: AZwV_QhHI8tiyq3gIThOgUAejBOgBYCkw1-AeDTb1Sc9pwMz7Z7ubQiEvh5te8Q Message-ID: Subject: Re: Attempting to delete excess rows from table with BATCH DELETE To: pgsql-general Content-Type: multipart/alternative; boundary="00000000000075de4e06496abf49" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000075de4e06496abf49 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Jan 27, 2026 at 10:22=E2=80=AFPM Gus Spier wr= ote: > Environment: AWS RDS Aurora for PostgreSQL 15 hosting tables that > support scientific research. The development environment predominantly > uses JPA with Hibernate. > > Years of neglect have allowed mission tables to accumulate hundreds of > millions of rows of excess data. The developers and the customer > decided we must delete all rows older than 75 days. Table partitioning > was briefly considered but discarded because of the effort needed to > refactor the codebase. > > I proposed the straight-forward course of action: delete by batches > from the victim tables. > > The solution seemed obvious: > > For candidate tables: > - Determine timestamp column iwith the most relevant value and call it > the Discriminator. > - Delete any row whose Discriminator value is 60 days older than the > Discriminator, with a LIMIT of 50000, > - Get the results of the batch by querying GET DIAGNOSTICS. That value > held aside for later use. > - COMMIT the delete transaction > - Loop to the top and continue deleting batches until there are no > more rows older than 60 days. > > - Before running a test, I ensure that the Discriminator column is indexe= d > > I write a procedure to accomplish all this work but it persists in > returning a error to the effect that a COMMIT is not valid in a block > tht tries to DELETE data. > > Has anybody seen this before? Yup, when putting the COMMIT in a DO block, which isn't allowed. > Is there a solution? > Loop using bash. In a similar case like this, I first looked for the oldest day's data in the tables, then did something like this bash pseudo-code: StopDate=3D$(date -d'60 days ago') DeleteDay=3D$1 export PGHOST=3Dfoo.example.com export PGDATABASE=3Dbar while [[ "$DeleteDay <=3D "$StopDate" ]]; do psql -Xc "DELETE FROM blarge WHERE txn_date > '$DeleteDay' + INTERVAL '1' DAY;" DeleteDay=3D$(date -d "$DeleteDay + 1 day" +"%Y-%m-%d") done Using that method, I developed a fast and automated monthly archive process which exported and then deleted from 120 tables. --=20 Death to , and butter sauce. Don't boil me, I'm still alive. lobster! --00000000000075de4e06496abf49 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Tue, Jan 27, 2026 at 10:22=E2=80=AFPM = Gus Spier <gus.spier@gmail.com> wrote:
Environment: AWS RDS Aurora for P= ostgreSQL 15 hosting tables that
support scientific research. The development environment predominantly
uses JPA with Hibernate.

Years of neglect have allowed mission tables to accumulate hundreds of
millions of rows of excess data. The developers and the customer
decided we must delete all rows older than 75 days. Table partitioning
was briefly considered but discarded because of the effort needed to
refactor the codebase.

I proposed the straight-forward course of action: delete by batches
from the victim tables.

The solution seemed obvious:

For candidate tables:
- Determine timestamp column iwith the most relevant value and call it
the Discriminator.
- Delete any row whose Discriminator value is 60 days older than the
Discriminator, with a LIMIT of 50000,
- Get the results of the batch by querying GET DIAGNOSTICS. That value
held aside for later use.
- COMMIT the delete transaction
- Loop to the top and continue deleting batches until there are no
more rows older than 60 days.

- Before running a test, I ensure that the Discriminator column is indexed<= br>
I write a procedure to accomplish all this work but it persists in
returning a error to the effect that a COMMIT is not valid in a block
tht tries to DELETE data.

Has anybody seen this before?

Yup, when put= ting the COMMIT in a DO block, which isn't allowed.
=C2=A0
Is there a solution?<= br>

Loop using bash.=C2=A0 In a similar cas= e like this, I first looked for the oldest day's data in the tables, th= en did something like this bash pseudo-code:
StopDate=3D$(date -d'60 days ago')
DeleteDay=3D$1
export PGDATABASE=3Dbar
while [[ "$DeleteDay <=3D &quo= t;$StopDate" ]]; do
=C2=A0 =C2=A0 psql -Xc "DELETE FROM blarge WHERE t= xn_date > '$DeleteDay' + INTERVAL '1' DAY;"<= /div>
=C2=A0 =C2=A0 DeleteDay=3D$(date -d &quo= t;$DeleteDay + 1 day" +"%Y-%m-%d")
done

Using that method= , I developed a fast and automated monthly archive process which exported a= nd then deleted from 120 tables.

--
Death to <Redacted>, and butter sauce.
Don&= #39;t boil me, I'm still alive.
<Redacted> lobster!<= /div>
--00000000000075de4e06496abf49--