16#include "catalog/pg_class_d.h"
43 bool echo,
bool verbose,
bool concurrently,
47 bool quiet,
bool verbose,
bool concurrently,
54 bool concurrently,
bool async,
60main(
int argc,
char *argv[])
62 static struct option long_options[] = {
89 const char *maintenance_db = NULL;
90 const char *host = NULL;
91 const char *
port = NULL;
96 bool syscatalog =
false;
101 bool concurrently =
false;
105 int concurrentCons = 1;
114 while ((
c =
getopt_long(argc, argv,
"ad:eh:i:j:qp:sS:t:U:vwW", long_options, &optindex)) != -1)
193 pg_log_error(
"too many command-line arguments (first is \"%s\")",
208 if (concurrentCons > 1 && syscatalog)
209 pg_fatal(
"cannot use multiple jobs to reindex system catalogs");
214 pg_fatal(
"cannot reindex all databases and a specific one at the same time");
216 cparams.
dbname = maintenance_db;
220 syscatalog, &schemas, &tables, &indexes);
226 if (getenv(
"PGDATABASE"))
227 dbname = getenv(
"PGDATABASE");
228 else if (getenv(
"PGUSER"))
229 dbname = getenv(
"PGUSER");
241 if (schemas.
head != NULL)
246 if (indexes.
head != NULL)
251 if (tables.
head != NULL)
260 if (!syscatalog && indexes.
head == NULL &&
261 tables.
head == NULL && schemas.
head == NULL)
274 bool verbose,
bool concurrently,
int concurrentCons,
280 bool parallel = concurrentCons > 1;
287 char *prev_index_table_name = NULL;
295 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
296 "concurrently",
"12");
302 pg_fatal(
"cannot use the \"%s\" option on server versions older than PostgreSQL %s",
308 switch (process_type)
317 Assert(user_list == NULL);
325 Assert(user_list != NULL);
331 switch (process_type)
341 if (process_list == NULL)
346 Assert(user_list != NULL);
354 if (process_list == NULL)
359 Assert(user_list != NULL);
372 if (user_list->
head == NULL)
379 Assert(indices_tables_list != NULL);
380 indices_tables_cell = indices_tables_list->
head;
404 for (cell = process_list->
head; cell; cell = cell->
next)
409 if (items_count >= concurrentCons)
412 concurrentCons =
Min(concurrentCons, items_count);
413 Assert(concurrentCons > 0);
415 Assert(process_list != NULL);
420 cell = process_list->
head;
423 const char *objname = cell->
val;
424 bool need_new_slot =
true;
440 if (prev_index_table_name != NULL &&
441 strcmp(prev_index_table_name, indices_tables_cell->
val) == 0)
442 need_new_slot =
false;
443 prev_index_table_name = indices_tables_cell->
val;
444 indices_tables_cell = indices_tables_cell->
next;
463 }
while (cell != NULL);
469 if (process_list != user_list)
475 if (indices_tables_list)
490 bool echo,
bool verbose,
bool concurrently,
bool async,
493 const char *paren =
"(";
494 const char *
comma =
", ";
495 const char *sep = paren;
583 pg_log_error(
"reindexing of database \"%s\" failed: %s",
587 pg_log_error(
"reindexing of index \"%s\" in database \"%s\" failed: %s",
591 pg_log_error(
"reindexing of schema \"%s\" in database \"%s\" failed: %s",
595 pg_log_error(
"reindexing of system catalogs in database \"%s\" failed: %s",
599 pg_log_error(
"reindexing of table \"%s\" in database \"%s\" failed: %s",
641 Assert(user_list == NULL);
643 "SELECT c.relname, ns.nspname\n"
644 " FROM pg_catalog.pg_class c\n"
645 " JOIN pg_catalog.pg_namespace ns"
646 " ON c.relnamespace = ns.oid\n"
647 " WHERE ns.nspname != 'pg_catalog'\n"
648 " AND c.relkind IN ("
651 " AND c.relpersistence != "
653 " ORDER BY c.relpages DESC;");
659 bool nsp_listed =
false;
661 Assert(user_list != NULL);
668 "SELECT c.relname, ns.nspname\n"
669 " FROM pg_catalog.pg_class c\n"
670 " JOIN pg_catalog.pg_namespace ns"
671 " ON c.relnamespace = ns.oid\n"
672 " WHERE c.relkind IN ("
675 " AND c.relpersistence != "
677 " AND ns.nspname IN (");
679 for (cell = user_list->
head; cell; cell = cell->
next)
681 const char *nspname = cell->
val;
692 " ORDER BY c.relpages DESC;");
700 Assert(user_list != NULL);
715 "SELECT t.relname, n.nspname, i.relname\n"
716 "FROM pg_catalog.pg_index x\n"
717 "JOIN pg_catalog.pg_class t ON t.oid = x.indrelid\n"
718 "JOIN pg_catalog.pg_class i ON i.oid = x.indexrelid\n"
719 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace\n"
720 "WHERE x.indexrelid OPERATOR(pg_catalog.=) ANY(ARRAY['");
722 for (cell = user_list->
head; cell; cell = cell->
next)
724 if (cell != user_list->
head)
735 "']::pg_catalog.regclass[])\n"
736 "ORDER BY max(i.relpages) OVER \n"
737 " (PARTITION BY n.nspname, t.relname),\n"
738 " n.nspname, t.relname, i.relpages;\n");
746 user_list->
head = user_list->
tail = NULL;
774 for (
i = 0;
i < ntups;
i++)
806 bool concurrently,
int concurrentCons,
817 "SELECT datname FROM pg_database WHERE datallowconn AND datconnlimit <> -2 ORDER BY 1;",
838 if (schemas->
head != NULL)
843 if (indexes->
head != NULL)
848 if (tables->
head != NULL)
857 if (!syscatalog && indexes->
head == NULL &&
858 tables->
head == NULL && schemas->
head == NULL)
874 printf(
_(
" -a, --all reindex all databases\n"));
875 printf(
_(
" --concurrently reindex concurrently\n"));
876 printf(
_(
" -d, --dbname=DBNAME database to reindex\n"));
877 printf(
_(
" -e, --echo show the commands being sent to the server\n"));
878 printf(
_(
" -i, --index=INDEX recreate specific index(es) only\n"));
879 printf(
_(
" -j, --jobs=NUM use this many concurrent connections to reindex\n"));
880 printf(
_(
" -q, --quiet don't write any messages\n"));
881 printf(
_(
" -s, --system reindex system catalogs only\n"));
882 printf(
_(
" -S, --schema=SCHEMA reindex specific schema(s) only\n"));
883 printf(
_(
" -t, --table=TABLE reindex specific table(s) only\n"));
884 printf(
_(
" --tablespace=TABLESPACE tablespace where indexes are rebuilt\n"));
885 printf(
_(
" -v, --verbose write a lot of output\n"));
886 printf(
_(
" -V, --version output version information, then exit\n"));
887 printf(
_(
" -?, --help show this help, then exit\n"));
888 printf(
_(
"\nConnection options:\n"));
889 printf(
_(
" -h, --host=HOSTNAME database server host or socket directory\n"));
890 printf(
_(
" -p, --port=PORT database server port\n"));
891 printf(
_(
" -U, --username=USERNAME user name to connect as\n"));
892 printf(
_(
" -w, --no-password never prompt for password\n"));
893 printf(
_(
" -W, --password force password prompt\n"));
894 printf(
_(
" --maintenance-db=DBNAME alternate maintenance database\n"));
895 printf(
_(
"\nRead the description of the SQL command REINDEX for details.\n"));
896 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
897 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
void appendQualifiedRelation(PQExpBuffer buf, const char *spec, PGconn *conn, bool echo)
#define Assert(condition)
#define PG_TEXTDOMAIN(domain)
volatile sig_atomic_t CancelRequested
void setup_cancel_handler(void(*query_cancel_callback)(void))
void set_pglocale_pgservice(const char *argv0, const char *app)
PGconn * connectMaintenanceDatabase(ConnParams *cparams, const char *progname, bool echo)
static void PGresult * res
int PQserverVersion(const PGconn *conn)
char * PQdb(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQntuples(const PGresult *res)
int PQsendQuery(PGconn *conn, const char *query)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
static void const char fflush(stdout)
void pg_logging_init(const char *argv0)
#define pg_log_error(...)
#define pg_log_error_hint(...)
void pfree(void *pointer)
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
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 PGconn * connectDatabase(const char *dbname, const char *connection_string, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error)
static PGresult * executeQuery(PGconn *conn, const char *query)
PGDLLIMPORT char * optarg
const char * get_progname(const char *argv0)
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)
bool executeMaintenanceCommand(PGconn *conn, const char *query, bool echo)
int main(int argc, char *argv[])
static void reindex_all_databases(ConnParams *cparams, const char *progname, bool echo, bool quiet, bool verbose, bool concurrently, int concurrentCons, const char *tablespace, bool syscatalog, SimpleStringList *schemas, SimpleStringList *tables, SimpleStringList *indexes)
static void help(const char *progname)
static void reindex_one_database(ConnParams *cparams, ReindexType type, SimpleStringList *user_list, const char *progname, bool echo, bool verbose, bool concurrently, int concurrentCons, const char *tablespace)
static SimpleStringList * get_parallel_object_list(PGconn *conn, ReindexType type, SimpleStringList *user_list, bool echo)
static void run_reindex_command(PGconn *conn, ReindexType type, const char *name, bool echo, bool verbose, bool concurrently, bool async, const char *tablespace)
void simple_string_list_append(SimpleStringList *list, const char *val)
void simple_string_list_destroy(SimpleStringList *list)
const char * fmtQualifiedId(const char *schema, const char *id)
const char * fmtId(const char *rawid)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
char val[FLEXIBLE_ARRAY_MEMBER]
struct SimpleStringListCell * next
SimpleStringListCell * head
SimpleStringListCell * tail
enum trivalue prompt_password
const char * get_user_name_or_exit(const char *progname)