Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit83dec5a

Browse files
committed
vacuumdb: don't prompt for passwords over and over
Having the script prompt for passwords over and over was a preexistingproblem when it processed multiple databases or when it processedmultiple analyze stages, but the parallel mode introduced in commita179232 made it worse.Fix the annoyance by keeping a copy of the password used by the firstconnection that requires one. Since users can (currently) only have asingle password, there's no need for more complex arrangements (such asremembering one password per database).Per bug #13741 reported by Eric Brown. Patch authored andcross-reviewed by Haribabu Kommi and Michael Paquier, slightly tweakedby Álvaro Herrera.Discussion:http://www.postgresql.org/message-id/20151027193919.931.54948@wrigleys.postgresql.orgBackpatch to 9.5, where parallel vacuumdb was introduced.
1 parentfe702a7 commit83dec5a

File tree

9 files changed

+98
-45
lines changed

9 files changed

+98
-45
lines changed

‎src/bin/scripts/clusterdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ cluster_one_database(const char *dbname, bool verbose, const char *table,
203203
appendPQExpBuffer(&sql," %s",table);
204204
appendPQExpBufferChar(&sql,';');
205205

206-
conn=connectDatabase(dbname,host,port,username,prompt_password,
206+
conn=connectDatabase(dbname,host,port,username,NULL,prompt_password,
207207
progname, false);
208208
if (!executeMaintenanceCommand(conn,sql.data,echo))
209209
{

‎src/bin/scripts/common.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,24 @@ handle_help_version_opts(int argc, char *argv[],
5252

5353

5454
/*
55-
* Make a database connection with the given parameters. An
56-
* interactive password prompt is automatically issued if required.
55+
* Make a database connection with the given parameters.
56+
*
57+
* A password can be given, but if not (or if user forces us to) we prompt
58+
* interactively for one, unless caller prohibited us from doing so.
5759
*/
5860
PGconn*
5961
connectDatabase(constchar*dbname,constchar*pghost,constchar*pgport,
60-
constchar*pguser,enumtrivalueprompt_password,
61-
constchar*progname,boolfail_ok)
62+
constchar*pguser,constchar*pgpassword,
63+
enumtrivalueprompt_password,constchar*progname,
64+
boolfail_ok)
6265
{
6366
PGconn*conn;
64-
char*password=NULL;
67+
char*password;
6568
boolnew_pass;
6669

67-
if (prompt_password==TRI_YES)
70+
password=pgpassword ?strdup(pgpassword) :NULL;
71+
72+
if (prompt_password==TRI_YES&& !pgpassword)
6873
password=simple_prompt("Password: ",100, false);
6974

7075
/*
@@ -95,22 +100,26 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
95100
new_pass= false;
96101
conn=PQconnectdbParams(keywords,values, true);
97102

98-
free(keywords);
99-
free(values);
100-
101103
if (!conn)
102104
{
103-
fprintf(stderr,_("%s: could not connect to database %s\n"),
105+
fprintf(stderr,_("%s: could not connect to database %s: out of memory\n"),
104106
progname,dbname);
105107
exit(1);
106108
}
107109

110+
pg_free(keywords);
111+
pg_free(values);
112+
113+
/*
114+
* No luck? Trying asking (again) for a password.
115+
*/
108116
if (PQstatus(conn)==CONNECTION_BAD&&
109117
PQconnectionNeedsPassword(conn)&&
110-
password==NULL&&
111118
prompt_password!=TRI_NO)
112119
{
113120
PQfinish(conn);
121+
if (password)
122+
free(password);
114123
password=simple_prompt("Password: ",100, false);
115124
new_pass= true;
116125
}
@@ -148,14 +157,14 @@ connectMaintenanceDatabase(const char *maintenance_db, const char *pghost,
148157

149158
/* If a maintenance database name was specified, just connect to it. */
150159
if (maintenance_db)
151-
returnconnectDatabase(maintenance_db,pghost,pgport,pguser,
160+
returnconnectDatabase(maintenance_db,pghost,pgport,pguser,NULL,
152161
prompt_password,progname, false);
153162

154163
/* Otherwise, try postgres first and then template1. */
155-
conn=connectDatabase("postgres",pghost,pgport,pguser,prompt_password,
156-
progname, true);
164+
conn=connectDatabase("postgres",pghost,pgport,pguser,NULL,
165+
prompt_password,progname, true);
157166
if (!conn)
158-
conn=connectDatabase("template1",pghost,pgport,pguser,
167+
conn=connectDatabase("template1",pghost,pgport,pguser,NULL,
159168
prompt_password,progname, false);
160169

161170
returnconn;

‎src/bin/scripts/common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ extern void handle_help_version_opts(int argc, char *argv[],
3131

3232
externPGconn*connectDatabase(constchar*dbname,constchar*pghost,
3333
constchar*pgport,constchar*pguser,
34-
enumtrivalueprompt_password,constchar*progname,
35-
boolfail_ok);
34+
constchar*pgpassword,enumtrivalueprompt_password,
35+
constchar*progname,boolfail_ok);
3636

3737
externPGconn*connectMaintenanceDatabase(constchar*maintenance_db,
3838
constchar*pghost,constchar*pgport,constchar*pguser,

‎src/bin/scripts/createlang.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ main(int argc, char *argv[])
140140
printQueryOptpopt;
141141
staticconstbooltranslate_columns[]= {false, true};
142142

143-
conn=connectDatabase(dbname,host,port,username,prompt_password,
144-
progname, false);
143+
conn=connectDatabase(dbname,host,port,username,NULL,
144+
prompt_password,progname, false);
145145

146146
printfPQExpBuffer(&sql,"SELECT lanname as \"%s\", "
147147
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
@@ -180,8 +180,8 @@ main(int argc, char *argv[])
180180
if (*p >='A'&&*p <='Z')
181181
*p+= ('a'-'A');
182182

183-
conn=connectDatabase(dbname,host,port,username,prompt_password,
184-
progname, false);
183+
conn=connectDatabase(dbname,host,port,username,NULL,
184+
prompt_password,progname, false);
185185

186186
/*
187187
* Make sure the language isn't already installed

‎src/bin/scripts/createuser.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ main(int argc, char *argv[])
250250
if (login==0)
251251
login=TRI_YES;
252252

253-
conn=connectDatabase("postgres",host,port,username,prompt_password,
254-
progname, false);
253+
conn=connectDatabase("postgres",host,port,username,NULL,
254+
prompt_password,progname, false);
255255

256256
initPQExpBuffer(&sql);
257257

‎src/bin/scripts/droplang.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ main(int argc, char *argv[])
139139
printQueryOptpopt;
140140
staticconstbooltranslate_columns[]= {false, true};
141141

142-
conn=connectDatabase(dbname,host,port,username,prompt_password,
143-
progname, false);
142+
conn=connectDatabase(dbname,host,port,username,NULL,
143+
prompt_password,progname, false);
144144

145145
printfPQExpBuffer(&sql,"SELECT lanname as \"%s\", "
146146
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
@@ -181,8 +181,8 @@ main(int argc, char *argv[])
181181
if (*p >='A'&&*p <='Z')
182182
*p+= ('a'-'A');
183183

184-
conn=connectDatabase(dbname,host,port,username,prompt_password,
185-
progname, false);
184+
conn=connectDatabase(dbname,host,port,username,NULL,
185+
prompt_password,progname, false);
186186

187187
/*
188188
* Force schema search path to be just pg_catalog, so that we don't have

‎src/bin/scripts/dropuser.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ main(int argc, char *argv[])
128128
appendPQExpBuffer(&sql,"DROP ROLE %s%s;",
129129
(if_exists ?"IF EXISTS " :""),fmtId(dropuser));
130130

131-
conn=connectDatabase("postgres",host,port,username,prompt_password,
132-
progname, false);
131+
conn=connectDatabase("postgres",host,port,username,NULL,
132+
prompt_password,progname, false);
133133

134134
if (echo)
135135
printf("%s\n",sql.data);

‎src/bin/scripts/reindexdb.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
297297
appendPQExpBuffer(&sql," DATABASE %s",fmtId(name));
298298
appendPQExpBufferChar(&sql,';');
299299

300-
conn=connectDatabase(dbname,host,port,username,prompt_password,
301-
progname, false);
300+
conn=connectDatabase(dbname,host,port,username,NULL,
301+
prompt_password,progname, false);
302302

303303
if (!executeMaintenanceCommand(conn,sql.data,echo))
304304
{
@@ -372,8 +372,8 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
372372

373373
appendPQExpBuffer(&sql," SYSTEM %s;",dbname);
374374

375-
conn=connectDatabase(dbname,host,port,username,prompt_password,
376-
progname, false);
375+
conn=connectDatabase(dbname,host,port,username,NULL,
376+
prompt_password,progname, false);
377377
if (!executeMaintenanceCommand(conn,sql.data,echo))
378378
{
379379
fprintf(stderr,_("%s: reindexing of system catalogs failed: %s"),

‎src/bin/scripts/vacuumdb.c

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
4343
constchar*host,constchar*port,
4444
constchar*username,enumtrivalueprompt_password,
4545
intconcurrentCons,
46-
constchar*progname,boolecho,boolquiet);
46+
constchar*progname,boolecho,boolquiet,
47+
char**password);
4748

4849
staticvoidvacuum_all_databases(vacuumingOptions*vacopts,
4950
boolanalyze_in_stages,
@@ -275,6 +276,8 @@ main(int argc, char *argv[])
275276
}
276277
else
277278
{
279+
char*password=NULL;
280+
278281
if (dbname==NULL)
279282
{
280283
if (getenv("PGDATABASE"))
@@ -296,7 +299,8 @@ main(int argc, char *argv[])
296299
&tables,
297300
host,port,username,prompt_password,
298301
concurrentCons,
299-
progname,echo,quiet);
302+
progname,echo,quiet,
303+
&password);
300304
}
301305
}
302306
else
@@ -305,7 +309,10 @@ main(int argc, char *argv[])
305309
&tables,
306310
host,port,username,prompt_password,
307311
concurrentCons,
308-
progname,echo,quiet);
312+
progname,echo,quiet,
313+
&password);
314+
315+
pg_free(password);
309316
}
310317

311318
exit(0);
@@ -323,15 +330,21 @@ main(int argc, char *argv[])
323330
* If concurrentCons is > 1, multiple connections are used to vacuum tables
324331
* in parallel. In this case and if the table list is empty, we first obtain
325332
* a list of tables from the database.
333+
*
334+
* 'password' is both an input and output parameter. If one is not passed,
335+
* then whatever is used in a connection is returned so that caller can
336+
* reuse it in future connections.
326337
*/
327338
staticvoid
328339
vacuum_one_database(constchar*dbname,vacuumingOptions*vacopts,
329340
intstage,
330341
SimpleStringList*tables,
331342
constchar*host,constchar*port,
332-
constchar*username,enumtrivalueprompt_password,
343+
constchar*username,
344+
enumtrivalueprompt_password,
333345
intconcurrentCons,
334-
constchar*progname,boolecho,boolquiet)
346+
constchar*progname,boolecho,boolquiet,
347+
char**password)
335348
{
336349
PQExpBufferDatasql;
337350
PGconn*conn;
@@ -365,8 +378,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
365378
fflush(stdout);
366379
}
367380

368-
conn=connectDatabase(dbname,host,port,username,prompt_password,
369-
progname, false);
381+
conn=connectDatabase(dbname,host,port,username,*password,
382+
prompt_password,progname, false);
383+
384+
/*
385+
* If no password was not specified by caller and the connection required
386+
* one, remember it; this suppresses further password prompts.
387+
*/
388+
if (PQconnectionUsedPassword(conn)&&*password==NULL)
389+
*password=pg_strdup(PQpass(conn));
370390

371391
initPQExpBuffer(&sql);
372392

@@ -424,10 +444,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
424444
init_slot(slots,conn);
425445
if (parallel)
426446
{
447+
constchar*pqpass;
448+
449+
/*
450+
* If a password was supplied for the initial connection, use it for
451+
* subsequent ones too. (Note that since we're connecting to the same
452+
* database with the same user, there's no need to update the stored
453+
* password any further.)
454+
*/
455+
pqpass=PQpass(conn);
456+
427457
for (i=1;i<concurrentCons;i++)
428458
{
429-
conn=connectDatabase(dbname,host,port,username,prompt_password,
430-
progname, false);
459+
conn=connectDatabase(dbname,host,port,username,pqpass,
460+
prompt_password,progname, false);
431461
init_slot(slots+i,conn);
432462
}
433463
}
@@ -542,12 +572,23 @@ vacuum_all_databases(vacuumingOptions *vacopts,
542572
PGresult*result;
543573
intstage;
544574
inti;
575+
char*password=NULL;
545576

546577
conn=connectMaintenanceDatabase(maintenance_db,host,port,
547578
username,prompt_password,progname);
579+
548580
result=executeQuery(conn,
549581
"SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;",
550582
progname,echo);
583+
584+
/*
585+
* Remember the password for further connections. If no password was
586+
* required for the maintenance db connection, this gets updated for the
587+
* first connection that does.
588+
*/
589+
if (PQconnectionUsedPassword(conn))
590+
password=pg_strdup(PQpass(conn));
591+
551592
PQfinish(conn);
552593

553594
if (analyze_in_stages)
@@ -572,7 +613,8 @@ vacuum_all_databases(vacuumingOptions *vacopts,
572613
NULL,
573614
host,port,username,prompt_password,
574615
concurrentCons,
575-
progname,echo,quiet);
616+
progname,echo,quiet,
617+
&password);
576618
}
577619
}
578620
}
@@ -588,11 +630,13 @@ vacuum_all_databases(vacuumingOptions *vacopts,
588630
NULL,
589631
host,port,username,prompt_password,
590632
concurrentCons,
591-
progname,echo,quiet);
633+
progname,echo,quiet,
634+
&password);
592635
}
593636
}
594637

595638
PQclear(result);
639+
pg_free(password);
596640
}
597641

598642
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp