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);
58 unsigned int tbl_count,
int concurrentCons,
59 const char *
progname,
bool echo,
bool quiet)
64 if (tbl_count > 0 && (concurrentCons > tbl_count))
65 concurrentCons = tbl_count;
69 cparams->
dbname = maintenance_db;
80 if (getenv(
"PGDATABASE"))
81 dbname = getenv(
"PGDATABASE");
82 else if (getenv(
"PGUSER"))
170 const char *
progname,
bool echo,
bool quiet)
179 bool free_retobjs =
false;
181 const char *stage_commands[] = {
182 "SET default_statistics_target=1; SET vacuum_cost_delay=0;",
183 "SET default_statistics_target=10; RESET vacuum_cost_delay;",
184 "RESET default_statistics_target;"
186 const char *stage_messages[] = {
187 gettext_noop(
"Generating minimal optimizer statistics (1 target)"),
188 gettext_noop(
"Generating medium optimizer statistics (10 targets)"),
189 gettext_noop(
"Generating default (full) optimizer statistics")
200 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
201 "disable-page-skipping",
"9.6");
207 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
208 "no-index-cleanup",
"12");
214 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
215 "force-index-cleanup",
"12");
221 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
222 "no-truncate",
"12");
228 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
229 "no-process-main",
"16");
235 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
236 "no-process-toast",
"14");
242 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
243 "skip-locked",
"12");
249 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
250 "--min-xid-age",
"9.6");
256 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
257 "--min-mxid-age",
"9.6");
263 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
270 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
271 "--buffer-usage-limit",
"16");
277 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
278 "--missing-stats-only",
"15");
287 printf(
_(
"%s: processing database \"%s\": %s\n"),
290 printf(
_(
"%s: vacuuming database \"%s\"\n"),
301 if (found_objs && *found_objs)
302 retobjs = *found_objs;
307 *found_objs = retobjs;
316 for (cell = retobjs->
head; cell; cell = cell->
next)
331 if (concurrentCons > ntups)
332 concurrentCons = ntups;
333 if (concurrentCons <= 0)
343 initcmd = stage_commands[stage];
359 cell = retobjs->
head;
362 const char *tabname = cell->
val;
390 }
while (cell != NULL);
401 const char *cmd =
"VACUUM (ONLY_DATABASE_STATS);";
439 const char *
progname,
bool echo,
bool quiet)
448 "SELECT datname FROM pg_database WHERE datallowconn AND datconnlimit <> -2 ORDER BY 1;",
470 for (
int i = 0;
i < numdbs;
i++)
487 for (
int i = 0;
i < numdbs;
i++)
494 for (
int i = 0;
i < numdbs;
i++)
534 bool objects_listed =
false;
537 for (cell = objects ? objects->
head : NULL; cell; cell = cell->
next)
539 char *just_table = NULL;
540 const char *just_columns = NULL;
545 "WITH listed_objects (object_oid, column_list) AS (\n"
547 objects_listed =
true;
567 &just_table, &just_columns);
573 if (just_columns && just_columns[0] !=
'\0')
593 " FROM pg_catalog.pg_class c\n"
594 " JOIN pg_catalog.pg_namespace ns"
595 " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
596 " CROSS JOIN LATERAL (SELECT c.relkind IN ("
598 CppAsString2(RELKIND_PARTITIONED_INDEX)
")) as p (inherited)\n"
599 " LEFT JOIN pg_catalog.pg_class t"
600 " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n");
609 " ON listed_objects.object_oid"
610 " OPERATOR(pg_catalog.=) ");
622 " WHERE c.relpersistence OPERATOR(pg_catalog.!=) "
633 " AND listed_objects.object_oid IS NULL\n");
636 " AND listed_objects.object_oid IS NOT NULL\n");
657 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
663 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
678 " AND GREATEST(pg_catalog.age(c.relfrozenxid),"
679 " pg_catalog.age(t.relfrozenxid)) "
680 " OPERATOR(pg_catalog.>=) '%d'::pg_catalog.int4\n"
681 " AND c.relfrozenxid OPERATOR(pg_catalog.!=)"
682 " '0'::pg_catalog.xid\n",
689 " AND GREATEST(pg_catalog.mxid_age(c.relminmxid),"
690 " pg_catalog.mxid_age(t.relminmxid)) OPERATOR(pg_catalog.>=)"
691 " '%d'::pg_catalog.int4\n"
692 " AND c.relminmxid OPERATOR(pg_catalog.!=)"
693 " '0'::pg_catalog.xid\n",
703 " EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
704 " WHERE a.attrelid OPERATOR(pg_catalog.=) c.oid\n"
705 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
706 " AND NOT a.attisdropped\n"
707 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
708 " AND a.attgenerated OPERATOR(pg_catalog.<>) "
710 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
711 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
712 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
713 " AND s.stainherit OPERATOR(pg_catalog.=) p.inherited))\n");
717 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext e\n"
718 " WHERE e.stxrelid OPERATOR(pg_catalog.=) c.oid\n"
719 " AND e.stxstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
720 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext_data d\n"
721 " WHERE d.stxoid OPERATOR(pg_catalog.=) e.oid\n"
722 " AND d.stxdinherit OPERATOR(pg_catalog.=) p.inherited))\n");
726 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
727 " JOIN pg_catalog.pg_index i"
728 " ON i.indexrelid OPERATOR(pg_catalog.=) a.attrelid\n"
729 " WHERE i.indrelid OPERATOR(pg_catalog.=) c.oid\n"
730 " AND i.indkey[a.attnum OPERATOR(pg_catalog.-) 1::pg_catalog.int2]"
731 " OPERATOR(pg_catalog.=) 0::pg_catalog.int2\n"
732 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
733 " AND NOT a.attisdropped\n"
734 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
735 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
736 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
737 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
738 " AND s.stainherit OPERATOR(pg_catalog.=) p.inherited))\n");
742 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_attribute a\n"
743 " WHERE a.attrelid OPERATOR(pg_catalog.=) c.oid\n"
744 " AND a.attnum OPERATOR(pg_catalog.>) 0::pg_catalog.int2\n"
745 " AND NOT a.attisdropped\n"
746 " AND a.attstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
747 " AND a.attgenerated OPERATOR(pg_catalog.<>) "
749 " AND c.relhassubclass\n"
750 " AND NOT p.inherited\n"
751 " AND EXISTS (SELECT NULL FROM pg_catalog.pg_inherits h\n"
752 " WHERE h.inhparent OPERATOR(pg_catalog.=) c.oid)\n"
753 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic s\n"
754 " WHERE s.starelid OPERATOR(pg_catalog.=) a.attrelid\n"
755 " AND s.staattnum OPERATOR(pg_catalog.=) a.attnum\n"
756 " AND s.stainherit))\n");
760 " OR EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext e\n"
761 " WHERE e.stxrelid OPERATOR(pg_catalog.=) c.oid\n"
762 " AND e.stxstattarget IS DISTINCT FROM 0::pg_catalog.int2\n"
763 " AND c.relhassubclass\n"
764 " AND NOT p.inherited\n"
765 " AND EXISTS (SELECT NULL FROM pg_catalog.pg_inherits h\n"
766 " WHERE h.inhparent OPERATOR(pg_catalog.=) c.oid)\n"
767 " AND NOT EXISTS (SELECT NULL FROM pg_catalog.pg_statistic_ext_data d\n"
768 " WHERE d.stxoid OPERATOR(pg_catalog.=) e.oid\n"
769 " AND d.stxdinherit))\n");
836 const char *paren =
" (";
837 const char *
comma =
", ";
838 const char *sep = paren;
848 if (serverVersion >= 110000)
853 Assert(serverVersion >= 120000);
864 Assert(serverVersion >= 160000);
883 if (serverVersion >= 90000)
888 Assert(serverVersion >= 90600);
895 Assert(serverVersion >= 120000);
903 Assert(serverVersion >= 120000);
911 Assert(serverVersion >= 120000);
918 Assert(serverVersion >= 160000);
925 Assert(serverVersion >= 140000);
932 Assert(serverVersion >= 160000);
939 Assert(serverVersion >= 120000);
966 Assert(serverVersion >= 130000);
973 Assert(serverVersion >= 160000);
1018 pg_log_error(
"vacuuming of table \"%s\" in database \"%s\" failed: %s",
1023 pg_log_error(
"vacuuming of 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)
void simple_string_list_destroy(SimpleStringList *list)
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)
static void free_retrieved_objects(SimpleStringList *list)
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