diff options
Diffstat (limited to 'src/bin/scripts/vacuumdb.c')
-rw-r--r-- | src/bin/scripts/vacuumdb.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 4ce27b78c54..6c67263f3c6 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -43,7 +43,8 @@ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, const char *host, const char *port, const char *username, enum trivalue prompt_password, int concurrentCons, - const char *progname, bool echo, bool quiet); + const char *progname, bool echo, bool quiet, + char **password); static void vacuum_all_databases(vacuumingOptions *vacopts, bool analyze_in_stages, @@ -275,6 +276,8 @@ main(int argc, char *argv[]) } else { + char *password = NULL; + if (dbname == NULL) { if (getenv("PGDATABASE")) @@ -296,7 +299,8 @@ main(int argc, char *argv[]) &tables, host, port, username, prompt_password, concurrentCons, - progname, echo, quiet); + progname, echo, quiet, + &password); } } else @@ -305,7 +309,10 @@ main(int argc, char *argv[]) &tables, host, port, username, prompt_password, concurrentCons, - progname, echo, quiet); + progname, echo, quiet, + &password); + + pg_free(password); } exit(0); @@ -323,15 +330,21 @@ main(int argc, char *argv[]) * If concurrentCons is > 1, multiple connections are used to vacuum tables * in parallel. In this case and if the table list is empty, we first obtain * a list of tables from the database. + * + * 'password' is both an input and output parameter. If one is not passed, + * then whatever is used in a connection is returned so that caller can + * reuse it in future connections. */ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, int stage, SimpleStringList *tables, const char *host, const char *port, - const char *username, enum trivalue prompt_password, + const char *username, + enum trivalue prompt_password, int concurrentCons, - const char *progname, bool echo, bool quiet) + const char *progname, bool echo, bool quiet, + char **password) { PQExpBufferData sql; PGconn *conn; @@ -365,8 +378,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, fflush(stdout); } - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(dbname, host, port, username, *password, + prompt_password, progname, false); + + /* + * If no password was not specified by caller and the connection required + * one, remember it; this suppresses further password prompts. + */ + if (PQconnectionUsedPassword(conn) && *password == NULL) + *password = pg_strdup(PQpass(conn)); initPQExpBuffer(&sql); @@ -424,10 +444,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, init_slot(slots, conn); if (parallel) { + const char *pqpass; + + /* + * If a password was supplied for the initial connection, use it for + * subsequent ones too. (Note that since we're connecting to the same + * database with the same user, there's no need to update the stored + * password any further.) + */ + pqpass = PQpass(conn); + for (i = 1; i < concurrentCons; i++) { - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(dbname, host, port, username, pqpass, + prompt_password, progname, false); init_slot(slots + i, conn); } } @@ -542,12 +572,23 @@ vacuum_all_databases(vacuumingOptions *vacopts, PGresult *result; int stage; int i; + char *password = NULL; conn = connectMaintenanceDatabase(maintenance_db, host, port, username, prompt_password, progname); + result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); + + /* + * Remember the password for further connections. If no password was + * required for the maintenance db connection, this gets updated for the + * first connection that does. + */ + if (PQconnectionUsedPassword(conn)) + password = pg_strdup(PQpass(conn)); + PQfinish(conn); if (analyze_in_stages) @@ -572,7 +613,8 @@ vacuum_all_databases(vacuumingOptions *vacopts, NULL, host, port, username, prompt_password, concurrentCons, - progname, echo, quiet); + progname, echo, quiet, + &password); } } } @@ -588,11 +630,13 @@ vacuum_all_databases(vacuumingOptions *vacopts, NULL, host, port, username, prompt_password, concurrentCons, - progname, echo, quiet); + progname, echo, quiet, + &password); } } PQclear(result); + pg_free(password); } /* |