15#include "catalog/pg_attribute_d.h"
16#include "catalog/pg_class_d.h"
33 const char *
progname,
bool echo,
bool quiet);
38 const char *
progname,
bool echo,
bool quiet);
57 unsigned int tbl_count,
int concurrentCons,
58 const char *
progname,
bool echo,
bool quiet)
63 if (tbl_count > 0 && (concurrentCons > tbl_count))
64 concurrentCons = tbl_count;
68 cparams->
dbname = maintenance_db;
79 if (getenv(
"PGDATABASE"))
80 dbname = getenv(
"PGDATABASE");
81 else if (getenv(
"PGUSER"))
165 const char *
progname,
bool echo,
bool quiet)
175 const char *stage_commands[] = {
176 "SET default_statistics_target=1; SET vacuum_cost_delay=0;",
177 "SET default_statistics_target=10; RESET vacuum_cost_delay;",
178 "RESET default_statistics_target;"
180 const char *stage_messages[] = {
181 gettext_noop(
"Generating minimal optimizer statistics (1 target)"),
182 gettext_noop(
"Generating medium optimizer statistics (10 targets)"),
183 gettext_noop(
"Generating default (full) optimizer statistics")
194 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
195 "disable-page-skipping",
"9.6");
201 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
202 "no-index-cleanup",
"12");
208 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
209 "force-index-cleanup",
"12");
215 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
216 "no-truncate",
"12");
222 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
223 "no-process-main",
"16");
229 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
230 "no-process-toast",
"14");
236 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
237 "skip-locked",
"12");
243 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
244 "--min-xid-age",
"9.6");
250 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
251 "--min-mxid-age",
"9.6");
257 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
264 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
265 "--buffer-usage-limit",
"16");
271 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
272 "--missing-stats-only",
"15");
281 printf(
_(
"%s: processing database \"%s\": %s\n"),
284 printf(
_(
"%s: vacuuming database \"%s\"\n"),
294 if (found_objs && *found_objs)
295 retobjs = *found_objs;
300 *found_objs = retobjs;
307 for (cell = retobjs ? retobjs->
head : NULL; cell; cell = cell->
next)
320 if (concurrentCons > ntups)
321 concurrentCons = ntups;
322 if (concurrentCons <= 0)
332 initcmd = stage_commands[stage];
348 cell = retobjs->
head;
351 const char *tabname = cell->
val;
379 }
while (cell != NULL);
390 const char *cmd =
"VACUUM (ONLY_DATABASE_STATS);";
426 const char *
progname,
bool echo,
bool quiet)
433 "SELECT datname FROM pg_database WHERE datallowconn AND datconnlimit <> -2 ORDER BY 1;",
513 bool objects_listed =
false;
516 for (cell = objects ? objects->
head : NULL; cell; cell = cell->
next)
518 char *just_table = NULL;
519 const char *just_columns = NULL;
524 "WITH listed_objects (object_oid, column_list) AS (\n"
526 objects_listed =
true;
546 &just_table, &just_columns);
552 if (just_columns && just_columns[0] !=
'\0')
572 " FROM pg_catalog.pg_class c\n"
573 " JOIN pg_catalog.pg_namespace ns"
574 " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
575 " CROSS JOIN LATERAL (SELECT c.relkind IN ("
577 CppAsString2(RELKIND_PARTITIONED_INDEX)
")) as p (inherited)\n"
578 " LEFT JOIN pg_catalog.pg_class t"
579 " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n");
588 " ON listed_objects.object_oid"
589 " OPERATOR(pg_catalog.=) ");
601 " WHERE c.relpersistence OPERATOR(pg_catalog.!=) "
612 " AND listed_objects.object_oid IS NULL\n");
615 " AND listed_objects.object_oid IS NOT NULL\n");
636 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
642 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
657 " AND GREATEST(pg_catalog.age(c.relfrozenxid),"
658 " pg_catalog.age(t.relfrozenxid)) "
659 " OPERATOR(pg_catalog.>=) '%d'::pg_catalog.int4\n"
660 " AND c.relfrozenxid OPERATOR(pg_catalog.!=)"
661 " '0'::pg_catalog.xid\n",
668 " AND GREATEST(pg_catalog.mxid_age(c.relminmxid),"
669 " pg_catalog.mxid_age(t.relminmxid)) OPERATOR(pg_catalog.>=)"
670 " '%d'::pg_catalog.int4\n"
671 " AND c.relminmxid OPERATOR(pg_catalog.!=)"
672 " '0'::pg_catalog.xid\n",
682 " EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
683 " WHERE a.attrelid OPERATOR(pg_catalog.=) c.oid\n"
684 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
685 " AND NOT a.attisdropped\n"
686 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
687 " AND a.attgenerated OPERATOR(pg_catalog.<>) "
689 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
690 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
691 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
692 " AND s.stainherit OPERATOR(pg_catalog.=) p.inherited))\n");
696 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext e\n"
697 " WHERE e.stxrelid OPERATOR(pg_catalog.=) c.oid\n"
698 " AND e.stxstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
699 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext_data d\n"
700 " WHERE d.stxoid OPERATOR(pg_catalog.=) e.oid\n"
701 " AND d.stxdinherit OPERATOR(pg_catalog.=) p.inherited))\n");
705 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
706 " JOIN pg_catalog.pg_index i"
707 " ON i.indexrelid OPERATOR(pg_catalog.=) a.attrelid\n"
708 " WHERE i.indrelid OPERATOR(pg_catalog.=) c.oid\n"
709 " AND i.indkey[a.attnum OPERATOR(pg_catalog.-) 1::pg_catalog.int2]"
710 " OPERATOR(pg_catalog.=) 0::pg_catalog.int2\n"
711 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
712 " AND NOT a.attisdropped\n"
713 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
714 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
715 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
716 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
717 " AND s.stainherit OPERATOR(pg_catalog.=) p.inherited))\n");
721 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
722 " WHERE a.attrelid OPERATOR(pg_catalog.=) c.oid\n"
723 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
724 " AND NOT a.attisdropped\n"
725 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
726 " AND a.attgenerated OPERATOR(pg_catalog.<>) "
728 " AND c.relhassubclass\n"
729 " AND NOT p.inherited\n"
730 " AND EXISTS (SELECT NULL FROM pg_catalog.pg_inherits h\n"
731 " WHERE h.inhparent OPERATOR(pg_catalog.=) c.oid)\n"
732 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
733 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
734 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
735 " AND s.stainherit))\n");
739 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext e\n"
740 " WHERE e.stxrelid OPERATOR(pg_catalog.=) c.oid\n"
741 " AND e.stxstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
742 " AND c.relhassubclass\n"
743 " AND NOT p.inherited\n"
744 " AND EXISTS (SELECT NULL FROM pg_catalog.pg_inherits h\n"
745 " WHERE h.inhparent OPERATOR(pg_catalog.=) c.oid)\n"
746 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext_data d\n"
747 " WHERE d.stxoid OPERATOR(pg_catalog.=) e.oid\n"
748 " AND d.stxdinherit))\n");
799 const char *paren =
" (";
800 const char *
comma =
", ";
801 const char *sep = paren;
811 if (serverVersion >= 110000)
816 Assert(serverVersion >= 120000);
827 Assert(serverVersion >= 160000);
846 if (serverVersion >= 90000)
851 Assert(serverVersion >= 90600);
858 Assert(serverVersion >= 120000);
866 Assert(serverVersion >= 120000);
874 Assert(serverVersion >= 120000);
881 Assert(serverVersion >= 160000);
888 Assert(serverVersion >= 140000);
895 Assert(serverVersion >= 160000);
902 Assert(serverVersion >= 120000);
929 Assert(serverVersion >= 130000);
936 Assert(serverVersion >= 160000);
981 pg_log_error(
"vacuuming of table \"%s\" in database \"%s\" failed: %s",
void splitTableColumnsSpec(const char *spec, int encoding, char **table, const char **columns)
volatile sig_atomic_t CancelRequested
void setup_cancel_handler(void(*query_cancel_callback)(void))
#define ALWAYS_SECURE_SEARCH_PATH_SQL
PGconn * connectMaintenanceDatabase(ConnParams *cparams, const char *progname, bool echo)
PGconn * connectDatabase(const ConnParams *cparams, const char *progname, bool echo, bool fail_ok, bool allow_password_reuse)
PGresult * executeQuery(PGconn *conn, const char *query)
int PQserverVersion(const PGconn *conn)
char * PQdb(const PGconn *conn)
int PQclientEncoding(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
int PQsendQuery(PGconn *conn, const char *query)
Assert(PointerIsAligned(start, uint64))
#define pg_log_error(...)
void * palloc0(Size size)
ParallelSlotArray * ParallelSlotsSetup(int numslots, ConnParams *cparams, const char *progname, bool echo, const char *initcmd)
bool ParallelSlotsWaitCompletion(ParallelSlotArray *sa)
bool TableCommandResultHandler(PGresult *res, PGconn *conn, void *context)
ParallelSlot * ParallelSlotsGetIdle(ParallelSlotArray *sa, const char *dbname)
void ParallelSlotsTerminate(ParallelSlotArray *sa)
void ParallelSlotsAdoptConn(ParallelSlotArray *sa, PGconn *conn)
static void ParallelSlotSetHandler(ParallelSlot *slot, ParallelSlotResultHandler handler, void *context)
static void executeCommand(PGconn *conn, const char *query)
static const struct lconv_member_info table[]
char * escape_single_quotes_ascii(const char *src)
void initPQExpBuffer(PQExpBuffer str)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
void simple_string_list_append(SimpleStringList *list, const char *val)
const char * fmtQualifiedIdEnc(const char *schema, const char *id, int encoding)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
char val[FLEXIBLE_ARRAY_MEMBER]
struct SimpleStringListCell * next
SimpleStringListCell * head
bool disable_page_skipping
char * buffer_usage_limit
const char * get_user_name_or_exit(const char *progname)
static SimpleStringList * retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, SimpleStringList *objects, bool echo)
static void prepare_vacuum_command(PGconn *conn, PQExpBuffer sql, vacuumingOptions *vacopts, const char *table)
static void run_vacuum_command(PGconn *conn, const char *sql, bool echo, const char *table)
static int vacuum_all_databases(ConnParams *cparams, vacuumingOptions *vacopts, SimpleStringList *objects, int concurrentCons, const char *progname, bool echo, bool quiet)
int vacuuming_main(ConnParams *cparams, const char *dbname, const char *maintenance_db, vacuumingOptions *vacopts, SimpleStringList *objects, unsigned int tbl_count, int concurrentCons, const char *progname, bool echo, bool quiet)
char * escape_quotes(const char *src)
static int vacuum_one_database(ConnParams *cparams, vacuumingOptions *vacopts, int stage, SimpleStringList *objects, SimpleStringList **found_objs, int concurrentCons, const char *progname, bool echo, bool quiet)
#define OBJFILTER_ALL_DBS
#define ANALYZE_NUM_STAGES
#define OBJFILTER_SCHEMA_EXCLUDE