Re: XX000: tuple concurrently deleted during DROP STATISTICS
Tomas Vondra <tomas.vondra@enterprisedb.com>
From: Tomas Vondra <tomas.vondra@enterprisedb.com>
To: Justin Pryzby <pryzby@telsasoft.com>, pgsql-hackers@postgresql.org
Date: 2023-11-08T15:27:40Z
Lists: pgsql-hackers
On 11/8/23 16:10, Justin Pryzby wrote: > I found this in our logs, and reproduced it under v11-v16. > > CREATE TABLE t(a int, b int); > INSERT INTO t SELECT generate_series(1,999); > CREATE STATISTICS t_stats ON a,b FROM t; > > while :; do psql postgres -qtxc "ANALYZE t"; done & > while :; do psql postgres -qtxc "begin; DROP STATISTICS t_stats"; done & > > It's known that concurrent DDL can hit elog(). But in this case, > there's only one DDL operation. > AFAICS this happens because store_statext (after ANALYZE builds the new statistics) does this: ---------------------------- /* * Delete the old tuple if it exists, and insert a new one. It's easier * than trying to update or insert, based on various conditions. */ RemoveStatisticsDataById(statOid, inh); /* form and insert a new tuple */ stup = heap_form_tuple(RelationGetDescr(pg_stextdata), values, nulls); CatalogTupleInsert(pg_stextdata, stup); ---------------------------- So it deletes the tuple first (if there's one), and then inserts the new statistics tuple. We could update the tuple instead, but that would be more complex (as the comment explains), and it doesn't actually fix anything because then simple_heap_delete just fails with TM_Updated instead. I think the only solution would be to lock the statistics tuple before running ANALYZE, or something like that. Or maybe we should even lock the statistics object itself, so that ANALYZE and DROP can't run concurrently on it? regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Commits
-
Lock table in DROP STATISTICS
- 4f8d3c5b5ade 12.18 landed
- 1e468ea4eace 13.14 landed
- 9dd50e92ed23 14.11 landed
- 0177fc773e3c 15.6 landed
- ee32b824dcc1 16.2 landed
- 28f84f72fbaf 17.0 landed