Skip to content

Commit 2e10863

Browse files
committed
Now that we allow ANALYZE to run inside a transaction block, the locks
it takes could be held for quite awhile after the analyze step completes. Rethink locking of pg_statistic in light of this fact. The original scheme took an exclusive lock on pg_statistic, which was okay when the lock could be expected to be released shortly, but that doesn't hold anymore. Back off to a normal writer's lock (RowExclusiveLock). This allows concurrent ANALYZE of nonoverlapping sets of tables, at the price that concurrent ANALYZEs of the same table may fail with 'tuple concurrently updated'.
1 parent 5c3102d commit 2e10863

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

src/backend/commands/analyze.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.41 2002/08/05 03:29:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.42 2002/08/11 00:08:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -272,7 +272,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
272272
*/
273273
if (attr_cnt <= 0)
274274
{
275-
relation_close(onerel, NoLock);
275+
relation_close(onerel, AccessShareLock);
276276
return;
277277
}
278278

@@ -1644,19 +1644,23 @@ compare_mcvs(const void *a, const void *b)
16441644
* This could possibly be made to work, but it's not worth the trouble.
16451645
* Note analyze_rel() has seen to it that we won't come here when
16461646
* vacuuming pg_statistic itself.
1647+
*
1648+
* Note: if two backends concurrently try to analyze the same relation,
1649+
* the second one is likely to fail here with a "tuple concurrently
1650+
* updated" error. This is slightly annoying, but no real harm is done.
1651+
* We could prevent the problem by using a stronger lock on the
1652+
* relation for ANALYZE (ie, ShareUpdateExclusiveLock instead
1653+
* of AccessShareLock); but that cure seems worse than the disease,
1654+
* especially now that ANALYZE doesn't start a new transaction
1655+
* for each relation. The lock could be held for a long time...
16471656
*/
16481657
static void
16491658
update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
16501659
{
16511660
Relation sd;
16521661
int attno;
16531662

1654-
/*
1655-
* We use an ExclusiveLock on pg_statistic to ensure that only one
1656-
* backend is writing it at a time --- without that, we might have to
1657-
* deal with concurrent updates here, and it's not worth the trouble.
1658-
*/
1659-
sd = heap_openr(StatisticRelationName, ExclusiveLock);
1663+
sd = heap_openr(StatisticRelationName, RowExclusiveLock);
16601664

16611665
for (attno = 0; attno < natts; attno++)
16621666
{
@@ -1789,6 +1793,5 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
17891793
heap_freetuple(stup);
17901794
}
17911795

1792-
/* close rel, but hold lock till upcoming commit */
1793-
heap_close(sd, NoLock);
1796+
heap_close(sd, RowExclusiveLock);
17941797
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy