Skip to content

Commit 9db4598

Browse files
committed
vacuumdb: Skip temporary tables in query to build list of relations
Running vacuumdb with a non-superuser while another user has created a temporary table would lead to a mid-flight permission failure, interrupting the operation. vacuum_rel() skips temporary relations of other backends, and it makes no sense for vacuumdb to know about these relations, so let's switch it to ignore temporary relations entirely. Adding a qual in the query based on relpersistence simplifies the generation of its WHERE clause in vacuum_one_database(), per se the removal of "has_where". Author: VaibhaveS, Michael Paquier Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAM_eQjwfAR=y3G1fGyS1U9FTmc+FyJm9amNfY2QCZBnDDbNPZg@mail.gmail.com Backpatch-through: 12
1 parent 14c57cb commit 9db4598

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

src/bin/scripts/vacuumdb.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,6 @@ vacuum_one_database(const ConnParams *cparams,
390390
bool failed = false;
391391
bool parallel = concurrentCons > 1;
392392
bool tables_listed = false;
393-
bool has_where = false;
394393
const char *stage_commands[] = {
395394
"SET default_statistics_target=1; SET vacuum_cost_delay=0;",
396395
"SET default_statistics_target=10; RESET vacuum_cost_delay;",
@@ -522,11 +521,21 @@ vacuum_one_database(const ConnParams *cparams,
522521
" LEFT JOIN pg_catalog.pg_class t"
523522
" ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n");
524523

525-
/* Used to match the tables listed by the user */
524+
/*
525+
* Used to match the tables listed by the user, completing the JOIN
526+
* clause.
527+
*/
526528
if (tables_listed)
527529
appendPQExpBufferStr(&catalog_query, " JOIN listed_tables"
528530
" ON listed_tables.table_oid OPERATOR(pg_catalog.=) c.oid\n");
529531

532+
/*
533+
* Exclude temporary tables, beginning the WHERE clause.
534+
*/
535+
appendPQExpBufferStr(&catalog_query,
536+
" WHERE c.relpersistence != " CppAsString2(RELPERSISTENCE_TEMP));
537+
538+
530539
/*
531540
* If no tables were listed, filter for the relevant relation types. If
532541
* tables were given via --table, don't bother filtering by relation type.
@@ -535,10 +544,9 @@ vacuum_one_database(const ConnParams *cparams,
535544
*/
536545
if (!tables_listed)
537546
{
538-
appendPQExpBufferStr(&catalog_query, " WHERE c.relkind OPERATOR(pg_catalog.=) ANY (array["
547+
appendPQExpBufferStr(&catalog_query, " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
539548
CppAsString2(RELKIND_RELATION) ", "
540549
CppAsString2(RELKIND_MATVIEW) "])\n");
541-
has_where = true;
542550
}
543551

544552
/*
@@ -551,25 +559,23 @@ vacuum_one_database(const ConnParams *cparams,
551559
if (vacopts->min_xid_age != 0)
552560
{
553561
appendPQExpBuffer(&catalog_query,
554-
" %s GREATEST(pg_catalog.age(c.relfrozenxid),"
562+
" AND GREATEST(pg_catalog.age(c.relfrozenxid),"
555563
" pg_catalog.age(t.relfrozenxid)) "
556564
" OPERATOR(pg_catalog.>=) '%d'::pg_catalog.int4\n"
557565
" AND c.relfrozenxid OPERATOR(pg_catalog.!=)"
558566
" '0'::pg_catalog.xid\n",
559-
has_where ? "AND" : "WHERE", vacopts->min_xid_age);
560-
has_where = true;
567+
vacopts->min_xid_age);
561568
}
562569

563570
if (vacopts->min_mxid_age != 0)
564571
{
565572
appendPQExpBuffer(&catalog_query,
566-
" %s GREATEST(pg_catalog.mxid_age(c.relminmxid),"
573+
" AND GREATEST(pg_catalog.mxid_age(c.relminmxid),"
567574
" pg_catalog.mxid_age(t.relminmxid)) OPERATOR(pg_catalog.>=)"
568575
" '%d'::pg_catalog.int4\n"
569576
" AND c.relminmxid OPERATOR(pg_catalog.!=)"
570577
" '0'::pg_catalog.xid\n",
571-
has_where ? "AND" : "WHERE", vacopts->min_mxid_age);
572-
has_where = true;
578+
vacopts->min_mxid_age);
573579
}
574580

575581
/*

0 commit comments

Comments
 (0)