Skip to content

Commit cabe0f2

Browse files
committed
Fix "ANALYZE t, t" inside a transaction block.
This failed with either "tuple already updated by self" or "duplicate key value violates unique constraint", depending on whether the table had previously been analyzed or not. The reason is that ANALYZE tried to insert or update the same pg_statistic rows twice, and there was no CommandCounterIncrement between. So add one. The same case works fine outside a transaction block, because then there's a whole transaction boundary between, as a consequence of the way VACUUM works. This issue has been latent all along, but the problem was unreachable before commit 11d8d72 added the ability to specify multiple tables in ANALYZE. We could, perhaps, alternatively fix it by adding code to de-duplicate the list of VacuumRelations --- but that would add a lot of overhead to work around dumb commands, so it's not attractive. Per bug #15946 from Yaroslav Schekin. Back-patch to v11. (Note: in v11 I also back-patched the test added by commit 2322456; otherwise the problem doesn't manifest in the test I added, because "vactst" is empty when the tests for multiple ANALYZE targets are reached. That seems like not a very good thing anyway, so I did this rather than rethinking the choice of test case.) Discussion: https://postgr.es/m/15946-5c7570a2884a26cf@postgresql.org
1 parent d8cd68c commit cabe0f2

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

src/backend/commands/vacuum.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,15 @@ vacuum(List *relations, VacuumParams *params,
418418
PopActiveSnapshot();
419419
CommitTransactionCommand();
420420
}
421+
else
422+
{
423+
/*
424+
* If we're not using separate xacts, better separate the
425+
* ANALYZE actions with CCIs. This avoids trouble if user
426+
* says "ANALYZE t, t".
427+
*/
428+
CommandCounterIncrement();
429+
}
421430
}
422431
}
423432
}

src/test/regress/expected/vacuum.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ ANALYZE vactst, does_not_exist, vacparted;
180180
ERROR: relation "does_not_exist" does not exist
181181
ANALYZE vactst (i), vacparted (does_not_exist);
182182
ERROR: column "does_not_exist" of relation "vacparted" does not exist
183+
ANALYZE vactst, vactst;
184+
BEGIN; -- ANALYZE behaves differently inside a transaction block
185+
ANALYZE vactst, vactst;
186+
COMMIT;
183187
-- parenthesized syntax for ANALYZE
184188
ANALYZE (VERBOSE) does_not_exist;
185189
ERROR: relation "does_not_exist" does not exist

src/test/regress/sql/vacuum.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ ANALYZE vactst, vacparted;
147147
ANALYZE vacparted (b), vactst;
148148
ANALYZE vactst, does_not_exist, vacparted;
149149
ANALYZE vactst (i), vacparted (does_not_exist);
150+
ANALYZE vactst, vactst;
151+
BEGIN; -- ANALYZE behaves differently inside a transaction block
152+
ANALYZE vactst, vactst;
153+
COMMIT;
150154

151155
-- parenthesized syntax for ANALYZE
152156
ANALYZE (VERBOSE) does_not_exist;

0 commit comments

Comments
 (0)